mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-10-31 11:17:34 -04:00 
			
		
		
		
	Merge pull request #9731 from turbo124/v5-develop
Adjustments for quote partial due dates
This commit is contained in:
		
						commit
						67f1166ccb
					
				| @ -62,10 +62,10 @@ class SendRemindersCron extends Command | |||||||
|     public function handle() |     public function handle() | ||||||
|     { |     { | ||||||
|         Invoice::where('next_send_date', '<=', now()->toDateTimeString()) |         Invoice::where('next_send_date', '<=', now()->toDateTimeString()) | ||||||
|                  ->whereNull('deleted_at') |                 ->whereNull('invoices.deleted_at') | ||||||
|                  ->where('is_deleted', 0) |                 ->where('invoices.is_deleted', 0) | ||||||
|                  ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) |                 ->whereIn('invoices.status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) | ||||||
|                  ->where('balance', '>', 0) |                 ->where('invoices.balance', '>', 0) | ||||||
|                  ->whereHas('client', function ($query) { |                  ->whereHas('client', function ($query) { | ||||||
|                      $query->where('is_deleted', 0) |                      $query->where('is_deleted', 0) | ||||||
|                            ->where('deleted_at', null); |                            ->where('deleted_at', null); | ||||||
| @ -73,6 +73,7 @@ class SendRemindersCron extends Command | |||||||
|                  ->whereHas('company', function ($query) { |                  ->whereHas('company', function ($query) { | ||||||
|                      $query->where('is_disabled', 0); |                      $query->where('is_disabled', 0); | ||||||
|                  }) |                  }) | ||||||
|  | 
 | ||||||
|                  ->with('invitations')->cursor()->each(function ($invoice) { |                  ->with('invitations')->cursor()->each(function ($invoice) { | ||||||
|                      if ($invoice->isPayable()) { |                      if ($invoice->isPayable()) { | ||||||
|                          $reminder_template = $invoice->calculateTemplate('invoice'); |                          $reminder_template = $invoice->calculateTemplate('invoice'); | ||||||
|  | |||||||
| @ -320,7 +320,7 @@ class InvoiceFilters extends QueryFilters | |||||||
|     { |     { | ||||||
|         $sort_col = explode('|', $sort); |         $sort_col = explode('|', $sort); | ||||||
| 
 | 
 | ||||||
|         if (!is_array($sort_col) || count($sort_col) != 2) { |         if (!is_array($sort_col) || count($sort_col) != 2 || in_array($sort_col[0], ['documents'])) { | ||||||
|             return $this->builder; |             return $this->builder; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -107,16 +107,16 @@ class InvoiceSumInclusive | |||||||
|     private function calculateCustomValues() |     private function calculateCustomValues() | ||||||
|     { |     { | ||||||
| 
 | 
 | ||||||
|         $this->total_taxes += $this->multiInclusiveTax($this->invoice->custom_surcharge1, $this->invoice->custom_surcharge_tax1); |         // $this->total_taxes += $this->multiInclusiveTax($this->invoice->custom_surcharge1, $this->invoice->custom_surcharge_tax1);
 | ||||||
|         $this->total_custom_values += $this->valuer($this->invoice->custom_surcharge1); |         $this->total_custom_values += $this->valuer($this->invoice->custom_surcharge1); | ||||||
| 
 | 
 | ||||||
|         $this->total_taxes += $this->multiInclusiveTax($this->invoice->custom_surcharge2, $this->invoice->custom_surcharge_tax2); |         // $this->total_taxes += $this->multiInclusiveTax($this->invoice->custom_surcharge2, $this->invoice->custom_surcharge_tax2);
 | ||||||
|         $this->total_custom_values += $this->valuer($this->invoice->custom_surcharge2); |         $this->total_custom_values += $this->valuer($this->invoice->custom_surcharge2); | ||||||
| 
 | 
 | ||||||
|         $this->total_taxes += $this->multiInclusiveTax($this->invoice->custom_surcharge3, $this->invoice->custom_surcharge_tax3); |         // $this->total_taxes += $this->multiInclusiveTax($this->invoice->custom_surcharge3, $this->invoice->custom_surcharge_tax3);
 | ||||||
|         $this->total_custom_values += $this->valuer($this->invoice->custom_surcharge3); |         $this->total_custom_values += $this->valuer($this->invoice->custom_surcharge3); | ||||||
| 
 | 
 | ||||||
|         $this->total_taxes += $this->multiInclusiveTax($this->invoice->custom_surcharge4, $this->invoice->custom_surcharge_tax4); |         // $this->total_taxes += $this->multiInclusiveTax($this->invoice->custom_surcharge4, $this->invoice->custom_surcharge_tax4);
 | ||||||
|         $this->total_custom_values += $this->valuer($this->invoice->custom_surcharge4); |         $this->total_custom_values += $this->valuer($this->invoice->custom_surcharge4); | ||||||
| 
 | 
 | ||||||
|         $this->total += $this->total_custom_values; |         $this->total += $this->total_custom_values; | ||||||
| @ -137,21 +137,21 @@ class InvoiceSumInclusive | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         //Handles cases where the surcharge is not taxed
 |         //Handles cases where the surcharge is not taxed
 | ||||||
|         // if(is_numeric($this->invoice->custom_surcharge1) && $this->invoice->custom_surcharge1 > 0 && !$this->invoice->custom_surcharge_tax1) {
 |         if(is_numeric($this->invoice->custom_surcharge1) && $this->invoice->custom_surcharge1 > 0 && $this->invoice->custom_surcharge_tax1) { | ||||||
|         //     $amount += $this->invoice->custom_surcharge1;
 |             $amount += $this->invoice->custom_surcharge1; | ||||||
|         // }
 |         } | ||||||
| 
 | 
 | ||||||
|         // if(is_numeric($this->invoice->custom_surcharge2) && $this->invoice->custom_surcharge2 > 0 && !$this->invoice->custom_surcharge_tax2) {
 |         if(is_numeric($this->invoice->custom_surcharge2) && $this->invoice->custom_surcharge2 > 0 && $this->invoice->custom_surcharge_tax2) { | ||||||
|         //     $amount += $this->invoice->custom_surcharge2;
 |             $amount += $this->invoice->custom_surcharge2; | ||||||
|         // }
 |         } | ||||||
| 
 | 
 | ||||||
|         // if(is_numeric($this->invoice->custom_surcharge3) && $this->invoice->custom_surcharge3 > 0 && !$this->invoice->custom_surcharge_tax3) {
 |         if(is_numeric($this->invoice->custom_surcharge3) && $this->invoice->custom_surcharge3 > 0 && $this->invoice->custom_surcharge_tax3) { | ||||||
|         //     $amount += $this->invoice->custom_surcharge3;
 |             $amount += $this->invoice->custom_surcharge3; | ||||||
|         // }
 |         } | ||||||
| 
 | 
 | ||||||
|         // if(is_numeric($this->invoice->custom_surcharge4) && $this->invoice->custom_surcharge4 > 0 && !$this->invoice->custom_surcharge_tax4) {
 |         if(is_numeric($this->invoice->custom_surcharge4) && $this->invoice->custom_surcharge4 > 0 && $this->invoice->custom_surcharge_tax4) { | ||||||
|         //     $amount += $this->invoice->custom_surcharge4;
 |             $amount += $this->invoice->custom_surcharge4; | ||||||
|         // }
 |         } | ||||||
| 
 | 
 | ||||||
|         if (is_string($this->invoice->tax_name1) && strlen($this->invoice->tax_name1) > 1) { |         if (is_string($this->invoice->tax_name1) && strlen($this->invoice->tax_name1) > 1) { | ||||||
|             $tax = $this->calcInclusiveLineTax($this->invoice->tax_rate1, $amount); |             $tax = $this->calcInclusiveLineTax($this->invoice->tax_rate1, $amount); | ||||||
|  | |||||||
| @ -81,14 +81,20 @@ class SearchController extends Controller | |||||||
|         $invoices = Invoice::query() |         $invoices = Invoice::query() | ||||||
|                      ->company() |                      ->company() | ||||||
|                      ->with('client') |                      ->with('client') | ||||||
|                      ->where('is_deleted', 0) |                      ->where('invoices.is_deleted', 0) | ||||||
|                      ->whereHas('client', function ($q) { |                     //  ->whereHas('client', function ($q) {
 | ||||||
|                          $q->where('is_deleted', 0); |                     //      $q->where('is_deleted', 0);
 | ||||||
|                      }) |                     //  })
 | ||||||
|  |                  | ||||||
|  |                     ->leftJoin('clients', function ($join) { | ||||||
|  |                         $join->on('invoices.client_id', '=', 'clients.id') | ||||||
|  |                             ->where('clients.is_deleted', 0); | ||||||
|  |                     }) | ||||||
|  |                       | ||||||
|                      ->when(!$user->hasPermission('view_all') || !$user->hasPermission('view_invoice'), function ($query) use ($user) { |                      ->when(!$user->hasPermission('view_all') || !$user->hasPermission('view_invoice'), function ($query) use ($user) { | ||||||
|                          $query->where('user_id', $user->id); |                          $query->where('invoices.user_id', $user->id); | ||||||
|                      }) |                      }) | ||||||
|                      ->orderBy('id', 'desc') |                      ->orderBy('invoices.id', 'desc') | ||||||
|                     ->take(3000) |                     ->take(3000) | ||||||
|                     ->get(); |                     ->get(); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -78,7 +78,9 @@ class StoreInvoiceRequest extends Request | |||||||
|         $rules['tax_name3'] = 'bail|sometimes|string|nullable'; |         $rules['tax_name3'] = 'bail|sometimes|string|nullable'; | ||||||
|         $rules['exchange_rate'] = 'bail|sometimes|numeric'; |         $rules['exchange_rate'] = 'bail|sometimes|numeric'; | ||||||
|         $rules['partial'] = 'bail|sometimes|nullable|numeric|gte:0'; |         $rules['partial'] = 'bail|sometimes|nullable|numeric|gte:0'; | ||||||
|         $rules['partial_due_date'] = ['bail', 'sometimes', 'exclude_if:partial,0', Rule::requiredIf(fn () => $this->partial > 0), 'date']; |         $rules['partial_due_date'] = ['bail', 'sometimes', 'nullable', 'exclude_if:partial,0', 'date', 'before:due_date', 'after_or_equal:date']; | ||||||
|  |         $rules['due_date'] = ['bail', 'sometimes', 'nullable', 'after:partial_due_date', Rule::requiredIf(fn () => strlen($this->partial_due_date ?? '') > 1), 'date']; | ||||||
|  | 
 | ||||||
|         $rules['amount'] = ['sometimes', 'bail', 'numeric', 'max:99999999999999']; |         $rules['amount'] = ['sometimes', 'bail', 'numeric', 'max:99999999999999']; | ||||||
| 
 | 
 | ||||||
|         // $rules['amount'] = ['sometimes', 'bail', 'max:99999999999999'];
 |         // $rules['amount'] = ['sometimes', 'bail', 'max:99999999999999'];
 | ||||||
|  | |||||||
| @ -82,8 +82,8 @@ class UpdateInvoiceRequest extends Request | |||||||
| 
 | 
 | ||||||
|         $rules['date'] = 'bail|sometimes|date:Y-m-d'; |         $rules['date'] = 'bail|sometimes|date:Y-m-d'; | ||||||
| 
 | 
 | ||||||
|         // $rules['partial_due_date'] = ['bail', 'sometimes', 'exclude_if:partial,0', Rule::requiredIf(fn () => $this->partial > 0), 'date', 'before:due_date'];
 |         $rules['partial_due_date'] = ['bail', 'sometimes', 'nullable', 'exclude_if:partial,0', 'date', 'before:due_date', 'after_or_equal:date']; | ||||||
|         // $rules['due_date'] = ['bail', 'sometimes', 'nullable', 'after:partial_due_date', Rule::requiredIf(fn () => strlen($this->partial_due_date) > 1), 'date'];
 |         $rules['due_date'] = ['bail', 'sometimes', 'nullable', 'after:partial_due_date', 'after_or_equal:date', Rule::requiredIf(fn () => strlen($this->partial_due_date) > 1), 'date']; | ||||||
| 
 | 
 | ||||||
|         return $rules; |         return $rules; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -66,8 +66,8 @@ class StoreQuoteRequest extends Request | |||||||
|         $rules['exchange_rate'] = 'bail|sometimes|numeric'; |         $rules['exchange_rate'] = 'bail|sometimes|numeric'; | ||||||
|         $rules['line_items'] = 'array'; |         $rules['line_items'] = 'array'; | ||||||
|         $rules['date'] = 'bail|sometimes|date:Y-m-d'; |         $rules['date'] = 'bail|sometimes|date:Y-m-d'; | ||||||
|         $rules['partial_due_date'] = ['bail', 'sometimes', 'exclude_if:partial,0', Rule::requiredIf(fn () => $this->partial > 0), 'date', 'before:due_date', 'after_or_equal:date']; |         $rules['partial_due_date'] = ['bail', 'sometimes', 'nullable', 'exclude_if:partial,0', 'date', 'before:due_date', 'after_or_equal:date']; | ||||||
|         $rules['due_date'] = ['bail', 'sometimes', 'nullable', 'after:partial_due_date', Rule::requiredIf(fn () => strlen($this->partial_due_date) > 1), 'date']; |         $rules['due_date'] = ['bail', 'sometimes', 'nullable', 'after:partial_due_date', Rule::requiredIf(fn () => strlen($this->partial_due_date ?? '') > 1), 'date']; | ||||||
|         $rules['amount'] = ['sometimes', 'bail', 'numeric', 'max:99999999999999']; |         $rules['amount'] = ['sometimes', 'bail', 'numeric', 'max:99999999999999']; | ||||||
| 
 | 
 | ||||||
|         return $rules; |         return $rules; | ||||||
|  | |||||||
| @ -65,7 +65,7 @@ class UpdateQuoteRequest extends Request | |||||||
| 
 | 
 | ||||||
|         $rules['date'] = 'bail|sometimes|date:Y-m-d'; |         $rules['date'] = 'bail|sometimes|date:Y-m-d'; | ||||||
| 
 | 
 | ||||||
|         $rules['partial_due_date'] = ['bail', 'sometimes', 'exclude_if:partial,0', Rule::requiredIf(fn () => $this->partial > 0), 'date', 'before:due_date']; |         $rules['partial_due_date'] = ['bail', 'sometimes', 'nullable', 'exclude_if:partial,0', 'date', 'before:due_date', 'after_or_equal:date']; | ||||||
|         $rules['due_date'] = ['bail', 'sometimes', 'nullable', 'after:partial_due_date', 'after_or_equal:date', Rule::requiredIf(fn () => strlen($this->partial_due_date) > 1), 'date']; |         $rules['due_date'] = ['bail', 'sometimes', 'nullable', 'after:partial_due_date', 'after_or_equal:date', Rule::requiredIf(fn () => strlen($this->partial_due_date) > 1), 'date']; | ||||||
|         $rules['amount'] = ['sometimes', 'bail', 'numeric', 'max:99999999999999']; |         $rules['amount'] = ['sometimes', 'bail', 'numeric', 'max:99999999999999']; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -48,12 +48,12 @@ class RecurringInvoicesCron | |||||||
|         Auth::logout(); |         Auth::logout(); | ||||||
| 
 | 
 | ||||||
|         if (! config('ninja.db.multi_db_enabled')) { |         if (! config('ninja.db.multi_db_enabled')) { | ||||||
|             $recurring_invoices = RecurringInvoice::query()->where('status_id', RecurringInvoice::STATUS_ACTIVE) |             $recurring_invoices = RecurringInvoice::query()->where('recurring_invoices.status_id', RecurringInvoice::STATUS_ACTIVE) | ||||||
|                                                         ->where('is_deleted', false) |                                                         ->where('recurring_invoices.is_deleted', false) | ||||||
|                                                         ->where('remaining_cycles', '!=', '0') |                                                         ->where('recurring_invoices.remaining_cycles', '!=', '0') | ||||||
|                                                         ->whereNotNull('next_send_date') |                                                         ->whereNotNull('recurring_invoices.next_send_date') | ||||||
|                                                         ->whereNull('deleted_at') |                                                         ->whereNull('recurring_invoices.deleted_at') | ||||||
|                                                         ->where('next_send_date', '<=', now()->toDateTimeString()) |                                                         ->where('recurring_invoices.next_send_date', '<=', now()->toDateTimeString()) | ||||||
|                                                         ->whereHas('client', function ($query) { |                                                         ->whereHas('client', function ($query) { | ||||||
|                                                             $query->where('is_deleted', 0) |                                                             $query->where('is_deleted', 0) | ||||||
|                                                                    ->where('deleted_at', null); |                                                                    ->where('deleted_at', null); | ||||||
| @ -87,18 +87,27 @@ class RecurringInvoicesCron | |||||||
|             foreach (MultiDB::$dbs as $db) { |             foreach (MultiDB::$dbs as $db) { | ||||||
|                 MultiDB::setDB($db); |                 MultiDB::setDB($db); | ||||||
| 
 | 
 | ||||||
|                 $recurring_invoices = RecurringInvoice::query()->where('status_id', RecurringInvoice::STATUS_ACTIVE) |                 $recurring_invoices = RecurringInvoice::query()->where('recurring_invoices.status_id', RecurringInvoice::STATUS_ACTIVE) | ||||||
|                                                         ->where('is_deleted', false) |                                                         ->where('recurring_invoices.is_deleted', false) | ||||||
|                                                         ->where('remaining_cycles', '!=', '0') |                                                         ->where('recurring_invoices.remaining_cycles', '!=', '0') | ||||||
|                                                         ->whereNull('deleted_at') |                                                         ->whereNull('recurring_invoices.deleted_at') | ||||||
|                                                         ->whereNotNull('next_send_date') |                                                         ->whereNotNull('recurring_invoices.next_send_date') | ||||||
|                                                         ->where('next_send_date', '<=', now()->toDateTimeString()) |                                                         ->where('recurring_invoices.next_send_date', '<=', now()->toDateTimeString()) | ||||||
|                                                         ->whereHas('client', function ($query) { |                                                         // ->whereHas('client', function ($query) {
 | ||||||
|                                                             $query->where('is_deleted', 0) |                                                         //     $query->where('is_deleted', 0)
 | ||||||
|                                                                    ->where('deleted_at', null); |                                                         //            ->where('deleted_at', null);
 | ||||||
|  |                                                         // })
 | ||||||
|  |                                                         // ->whereHas('company', function ($query) {
 | ||||||
|  |                                                         //     $query->where('is_disabled', 0);
 | ||||||
|  |                                                         // })
 | ||||||
|  |                                                         ->leftJoin('clients', function ($join) { | ||||||
|  |                                                             $join->on('recurring_invoices.client_id', '=', 'clients.id') | ||||||
|  |                                                                 ->where('clients.is_deleted', 0) | ||||||
|  |                                                                 ->whereNull('clients.deleted_at'); | ||||||
|                                                         }) |                                                         }) | ||||||
|                                                         ->whereHas('company', function ($query) { |                                                         ->leftJoin('companies', function ($join) { | ||||||
|                                                             $query->where('is_disabled', 0); |                                                             $join->on('recurring_invoices.company_id', '=', 'companies.id') | ||||||
|  |                                                                 ->where('companies.is_disabled', 0); | ||||||
|                                                         }) |                                                         }) | ||||||
|                                                         ->with('company') |                                                         ->with('company') | ||||||
|                                                         ->cursor(); |                                                         ->cursor(); | ||||||
|  | |||||||
| @ -51,20 +51,29 @@ class InvoiceCheckLateWebhook implements ShouldQueue | |||||||
|                                   ->pluck('company_id'); |                                   ->pluck('company_id'); | ||||||
| 
 | 
 | ||||||
|             Invoice::query() |             Invoice::query() | ||||||
|                  ->where('is_deleted', false) |                  ->where('invoices.is_deleted', false) | ||||||
|                  ->whereNull('deleted_at') |                  ->whereNull('invoices.deleted_at') | ||||||
|                  ->whereNotNull('due_date') |                  ->whereNotNull('invoices.due_date') | ||||||
|                  ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) |                  ->whereIn('invoices.status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) | ||||||
|                  ->where('balance', '>', 0) |                  ->where('invoices.balance', '>', 0) | ||||||
|                  ->whereIn('company_id', $company_ids) |                  ->whereIn('invoices.company_id', $company_ids) | ||||||
|                  ->whereHas('client', function ($query) { |                 //  ->whereHas('client', function ($query) {
 | ||||||
|                      $query->where('is_deleted', 0) |                 //      $query->where('is_deleted', 0)
 | ||||||
|                             ->where('deleted_at', null); |                 //             ->where('deleted_at', null);
 | ||||||
|                  }) |                 //  })
 | ||||||
|                     ->whereHas('company', function ($query) { |                 //     ->whereHas('company', function ($query) {
 | ||||||
|                         $query->where('is_disabled', 0); |                 //         $query->where('is_disabled', 0);
 | ||||||
|                     }) |                 //     })
 | ||||||
|                  ->whereBetween('due_date', [now()->subDay()->startOfDay(), now()->startOfDay()->subSecond()]) |                 ->leftJoin('clients', function ($join) { | ||||||
|  |                     $join->on('invoices.client_id', '=', 'clients.id') | ||||||
|  |                         ->where('clients.is_deleted', 0) | ||||||
|  |                         ->whereNull('clients.deleted_at'); | ||||||
|  |                 }) | ||||||
|  |                 ->leftJoin('companies', function ($join) { | ||||||
|  |                     $join->on('invoices.company_id', '=', 'companies.id') | ||||||
|  |                         ->where('companies.is_disabled', 0); | ||||||
|  |                 }) | ||||||
|  |                  ->whereBetween('invoices.due_date', [now()->subDay()->startOfDay(), now()->startOfDay()->subSecond()]) | ||||||
|                  ->cursor() |                  ->cursor() | ||||||
|                  ->each(function ($invoice) { |                  ->each(function ($invoice) { | ||||||
|                      (new WebhookHandler(Webhook::EVENT_LATE_INVOICE, $invoice, $invoice->company, 'client'))->handle(); |                      (new WebhookHandler(Webhook::EVENT_LATE_INVOICE, $invoice, $invoice->company, 'client'))->handle(); | ||||||
| @ -78,20 +87,29 @@ class InvoiceCheckLateWebhook implements ShouldQueue | |||||||
|                                       ->pluck('company_id'); |                                       ->pluck('company_id'); | ||||||
| 
 | 
 | ||||||
|                 Invoice::query() |                 Invoice::query() | ||||||
|                      ->where('is_deleted', false) |                      ->where('invoices.is_deleted', false) | ||||||
|                      ->whereNull('deleted_at') |                      ->whereNull('invoices.deleted_at') | ||||||
|                      ->whereNotNull('due_date') |                      ->whereNotNull('invoices.due_date') | ||||||
|                      ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) |                      ->whereIn('invoices.status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) | ||||||
|                      ->where('balance', '>', 0) |                      ->where('invoices.balance', '>', 0) | ||||||
|                      ->whereIn('company_id', $company_ids) |                      ->whereIn('invoices.company_id', $company_ids) | ||||||
|                      ->whereHas('client', function ($query) { |                     //  ->whereHas('client', function ($query) {
 | ||||||
|                          $query->where('is_deleted', 0) |                     //      $query->where('is_deleted', 0)
 | ||||||
|                                 ->where('deleted_at', null); |                     //             ->where('deleted_at', null);
 | ||||||
|                      }) |                     //  })
 | ||||||
|                         ->whereHas('company', function ($query) { |                     //     ->whereHas('company', function ($query) {
 | ||||||
|                             $query->where('is_disabled', 0); |                     //         $query->where('is_disabled', 0);
 | ||||||
|                         }) |                     //     })
 | ||||||
|                      ->whereBetween('due_date', [now()->subDay()->startOfDay(), now()->startOfDay()->subSecond()]) |                     ->leftJoin('clients', function ($join) { | ||||||
|  |                         $join->on('invoices.client_id', '=', 'clients.id') | ||||||
|  |                             ->where('clients.is_deleted', 0) | ||||||
|  |                             ->whereNull('clients.deleted_at'); | ||||||
|  |                     }) | ||||||
|  |                     ->leftJoin('companies', function ($join) { | ||||||
|  |                         $join->on('invoices.company_id', '=', 'companies.id') | ||||||
|  |                             ->where('companies.is_disabled', 0); | ||||||
|  |                     }) | ||||||
|  |                      ->whereBetween('invoices.due_date', [now()->subDay()->startOfDay(), now()->startOfDay()->subSecond()]) | ||||||
|                      ->cursor() |                      ->cursor() | ||||||
|                      ->each(function ($invoice) { |                      ->each(function ($invoice) { | ||||||
|                          (new WebhookHandler(Webhook::EVENT_LATE_INVOICE, $invoice, $invoice->company, 'client'))->handle(); |                          (new WebhookHandler(Webhook::EVENT_LATE_INVOICE, $invoice, $invoice->company, 'client'))->handle(); | ||||||
|  | |||||||
| @ -49,10 +49,10 @@ class QuoteCheckExpired implements ShouldQueue | |||||||
|     { |     { | ||||||
|         if (! config('ninja.db.multi_db_enabled')) { |         if (! config('ninja.db.multi_db_enabled')) { | ||||||
|             Quote::query() |             Quote::query() | ||||||
|                  ->where('status_id', Quote::STATUS_SENT) |                  ->where('quotes.status_id', Quote::STATUS_SENT) | ||||||
|                  ->where('is_deleted', false) |                  ->where('quotes.is_deleted', false) | ||||||
|                  ->whereNull('deleted_at') |                  ->whereNull('quotes.deleted_at') | ||||||
|                  ->whereNotNull('due_date') |                  ->whereNotNull('quotes.due_date') | ||||||
|                  ->whereHas('client', function ($query) { |                  ->whereHas('client', function ($query) { | ||||||
|                      $query->where('is_deleted', 0) |                      $query->where('is_deleted', 0) | ||||||
|                             ->where('deleted_at', null); |                             ->where('deleted_at', null); | ||||||
| @ -60,8 +60,8 @@ class QuoteCheckExpired implements ShouldQueue | |||||||
|                     ->whereHas('company', function ($query) { |                     ->whereHas('company', function ($query) { | ||||||
|                         $query->where('is_disabled', 0); |                         $query->where('is_disabled', 0); | ||||||
|                     }) |                     }) | ||||||
|                  // ->where('due_date', '<='. now()->toDateTimeString())
 |                  | ||||||
|                  ->whereBetween('due_date', [now()->subDay()->startOfDay(), now()->startOfDay()->subSecond()]) |                  ->whereBetween('quotes.due_date', [now()->subDay()->startOfDay(), now()->startOfDay()->subSecond()]) | ||||||
|                  ->cursor() |                  ->cursor() | ||||||
|                  ->each(function ($quote) { |                  ->each(function ($quote) { | ||||||
|                      $this->queueExpiredQuoteNotification($quote); |                      $this->queueExpiredQuoteNotification($quote); | ||||||
| @ -71,10 +71,10 @@ class QuoteCheckExpired implements ShouldQueue | |||||||
|                 MultiDB::setDB($db); |                 MultiDB::setDB($db); | ||||||
| 
 | 
 | ||||||
|                 Quote::query() |                 Quote::query() | ||||||
|                     ->where('status_id', Quote::STATUS_SENT) |                     ->where('quotes.status_id', Quote::STATUS_SENT) | ||||||
|                     ->where('is_deleted', false) |                     ->where('quotes.is_deleted', false) | ||||||
|                     ->whereNull('deleted_at') |                     ->whereNull('quotes.deleted_at') | ||||||
|                     ->whereNotNull('due_date') |                     ->whereNotNull('quotes.due_date') | ||||||
|                     ->whereHas('client', function ($query) { |                     ->whereHas('client', function ($query) { | ||||||
|                         $query->where('is_deleted', 0) |                         $query->where('is_deleted', 0) | ||||||
|                                ->where('deleted_at', null); |                                ->where('deleted_at', null); | ||||||
| @ -82,8 +82,8 @@ class QuoteCheckExpired implements ShouldQueue | |||||||
|                        ->whereHas('company', function ($query) { |                        ->whereHas('company', function ($query) { | ||||||
|                            $query->where('is_disabled', 0); |                            $query->where('is_disabled', 0); | ||||||
|                        }) |                        }) | ||||||
|                     // ->where('due_date', '<='. now()->toDateTimeString())
 |                      | ||||||
|                     ->whereBetween('due_date', [now()->subDay()->startOfDay(), now()->startOfDay()->subSecond()]) |                     ->whereBetween('quotes.due_date', [now()->subDay()->startOfDay(), now()->startOfDay()->subSecond()]) | ||||||
|                     ->cursor() |                     ->cursor() | ||||||
|                     ->each(function ($quote) { |                     ->each(function ($quote) { | ||||||
|                         $this->queueExpiredQuoteNotification($quote); |                         $this->queueExpiredQuoteNotification($quote); | ||||||
|  | |||||||
| @ -61,10 +61,10 @@ class QuoteReminderJob implements ShouldQueue | |||||||
|             nrlog("Sending quote reminders on ".now()->format('Y-m-d h:i:s')); |             nrlog("Sending quote reminders on ".now()->format('Y-m-d h:i:s')); | ||||||
| 
 | 
 | ||||||
|             Quote::query() |             Quote::query() | ||||||
|                  ->where('is_deleted', 0) |                  ->where('quotes.is_deleted', 0) | ||||||
|                  ->whereIn('status_id', [Invoice::STATUS_SENT]) |                  ->whereIn('quotes.status_id', [Invoice::STATUS_SENT]) | ||||||
|                  ->whereNull('deleted_at') |                  ->whereNull('quotes.deleted_at') | ||||||
|                  ->where('next_send_date', '<=', now()->toDateTimeString()) |                  ->where('quotes.next_send_date', '<=', now()->toDateTimeString()) | ||||||
|                  ->whereHas('client', function ($query) { |                  ->whereHas('client', function ($query) { | ||||||
|                      $query->where('is_deleted', 0) |                      $query->where('is_deleted', 0) | ||||||
|                            ->where('deleted_at', null); |                            ->where('deleted_at', null); | ||||||
| @ -88,10 +88,10 @@ class QuoteReminderJob implements ShouldQueue | |||||||
|                 nrlog("Sending quote reminders on db {$db} ".now()->format('Y-m-d h:i:s')); |                 nrlog("Sending quote reminders on db {$db} ".now()->format('Y-m-d h:i:s')); | ||||||
| 
 | 
 | ||||||
|                 Quote::query() |                 Quote::query() | ||||||
|                      ->where('is_deleted', 0) |                      ->where('quotes.is_deleted', 0) | ||||||
|                      ->whereIn('status_id', [Invoice::STATUS_SENT]) |                      ->whereIn('quotes.status_id', [Invoice::STATUS_SENT]) | ||||||
|                      ->whereNull('deleted_at') |                      ->whereNull('quotes.deleted_at') | ||||||
|                      ->where('next_send_date', '<=', now()->toDateTimeString()) |                      ->where('quotes.next_send_date', '<=', now()->toDateTimeString()) | ||||||
|                      ->whereHas('client', function ($query) { |                      ->whereHas('client', function ($query) { | ||||||
|                          $query->where('is_deleted', 0) |                          $query->where('is_deleted', 0) | ||||||
|                                ->where('deleted_at', null); |                                ->where('deleted_at', null); | ||||||
| @ -99,6 +99,7 @@ class QuoteReminderJob implements ShouldQueue | |||||||
|                      ->whereHas('company', function ($query) { |                      ->whereHas('company', function ($query) { | ||||||
|                          $query->where('is_disabled', 0); |                          $query->where('is_disabled', 0); | ||||||
|                      }) |                      }) | ||||||
|  |                      | ||||||
|                      ->with('invitations')->chunk(50, function ($quotes) { |                      ->with('invitations')->chunk(50, function ($quotes) { | ||||||
| 
 | 
 | ||||||
|                          foreach ($quotes as $quote) { |                          foreach ($quotes as $quote) { | ||||||
|  | |||||||
| @ -47,11 +47,10 @@ class ExpenseRepository extends BaseRepository | |||||||
|         $user = auth()->user(); |         $user = auth()->user(); | ||||||
| 
 | 
 | ||||||
|         $payment_date = &$data['payment_date']; |         $payment_date = &$data['payment_date']; | ||||||
|         $vendor_id = &$data['vendor_id']; |  | ||||||
| 
 | 
 | ||||||
|         if($payment_date && $payment_date == $expense->payment_date) { |         if($payment_date && $payment_date == $expense->payment_date) { | ||||||
|             //do nothing
 |             //do nothing
 | ||||||
|         } elseif($payment_date && strlen($payment_date) > 1 && $user->company()->notify_vendor_when_paid && ($vendor_id || $expense->vendor_id)) { |         } elseif($payment_date && strlen($payment_date) > 1 && $user->company()->notify_vendor_when_paid && (isset($data['vendor_id']) || $expense->vendor_id)) { | ||||||
|             $this->notify_vendor = true; |             $this->notify_vendor = true; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -90,15 +90,15 @@ class ARDetailReport extends BaseExport | |||||||
|         $this->csv->insertOne($this->buildHeader()); |         $this->csv->insertOne($this->buildHeader()); | ||||||
| 
 | 
 | ||||||
|         $query = Invoice::query() |         $query = Invoice::query() | ||||||
|  |                 ->whereIn('invoices.status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) | ||||||
|                 ->withTrashed() |                 ->withTrashed() | ||||||
|                 ->whereHas('client', function ($query) { |                 ->whereHas('client', function ($query) { | ||||||
|                     $query->where('is_deleted', 0); |                     $query->where('is_deleted', 0); | ||||||
|                 }) |                 }) | ||||||
|                 ->where('company_id', $this->company->id) |                 ->where('invoices.company_id', $this->company->id) | ||||||
|                 ->where('is_deleted', 0) |                 ->where('invoices.is_deleted', 0) | ||||||
|                 ->where('balance', '>', 0) |                 ->where('invoices.balance', '>', 0) | ||||||
|                 ->orderBy('due_date', 'ASC') |                 ->orderBy('invoices.due_date', 'ASC'); | ||||||
|                 ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]); |  | ||||||
| 
 | 
 | ||||||
|         $query = $this->addDateRange($query, 'invoices'); |         $query = $this->addDateRange($query, 'invoices'); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -39,7 +39,7 @@ trait PdfMaker | |||||||
|             $pdf->addChromiumArguments(config('ninja.snappdf_chromium_arguments')); |             $pdf->addChromiumArguments(config('ninja.snappdf_chromium_arguments')); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         $html = str_replace(['file:/', 'iframe', '<object', '<object', '127.0.0.1', 'localhost'], ['','','','','',''], $html); |         $html = str_ireplace(['file:/', 'iframe', '<embed', '<embed', '<object', '<object', '127.0.0.1', 'localhost'], '', $html); | ||||||
| 
 | 
 | ||||||
|         $generated = $pdf |         $generated = $pdf | ||||||
|                         ->setHtml($html) |                         ->setHtml($html) | ||||||
|  | |||||||
| @ -101,18 +101,7 @@ | |||||||
|             </dl> |             </dl> | ||||||
|         </div> |         </div> | ||||||
| 
 | 
 | ||||||
| 
 |         @if($invoice->subscription && $invoice->subscription?->allow_cancellation && $invoice->status_id == 2) | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         @if($invoice->subscription && $invoice->subscription?->allow_cancellation) |  | ||||||
|         {{-- INV2-591 --}} |  | ||||||
|         {{-- @if(false) --}} |  | ||||||
|         <div class="bg-white shadow sm:rounded-lg mt-4"> |         <div class="bg-white shadow sm:rounded-lg mt-4"> | ||||||
|             <div class="px-4 py-5 sm:p-6"> |             <div class="px-4 py-5 sm:p-6"> | ||||||
|                 <div class="sm:flex sm:items-start sm:justify-between"> |                 <div class="sm:flex sm:items-start sm:justify-between"> | ||||||
|  | |||||||
| @ -73,7 +73,7 @@ | |||||||
|             </div> |             </div> | ||||||
|         @endif |         @endif | ||||||
| 
 | 
 | ||||||
|         @if($invoice->subscription && $invoice->subscription?->allow_cancellation) |         @if($invoice->subscription && $invoice->subscription?->allow_cancellation && $invoice->status_id == 2) | ||||||
|         <div class="bg-white shadow sm:rounded-lg mt-4"> |         <div class="bg-white shadow sm:rounded-lg mt-4"> | ||||||
|             <div class="px-4 py-5 sm:p-6"> |             <div class="px-4 py-5 sm:p-6"> | ||||||
|                 <div class="sm:flex sm:items-start sm:justify-between"> |                 <div class="sm:flex sm:items-start sm:justify-between"> | ||||||
| @ -92,7 +92,7 @@ | |||||||
|         </div> |         </div> | ||||||
|         @endif |         @endif | ||||||
| 
 | 
 | ||||||
|         @if($invoice->subscription && $invoice->subscription->allow_plan_changes) |         @if($invoice->subscription && $invoice->subscription->allow_plan_changes && count($invoice->subscription->service()->getPlans()) > 0) | ||||||
|             <div class="bg-white shadow overflow-hidden px-4 py-5 lg:rounded-lg mt-4"> |             <div class="bg-white shadow overflow-hidden px-4 py-5 lg:rounded-lg mt-4"> | ||||||
|                 <h3 class="text-lg leading-6 font-medium text-gray-900">{{ ctrans('texts.change_plan') }}</h3> |                 <h3 class="text-lg leading-6 font-medium text-gray-900">{{ ctrans('texts.change_plan') }}</h3> | ||||||
|                 <p class="mt-1 max-w-2xl text-sm leading-5 text-gray-500">{{ ctrans('texts.change_plan_description') }}</p> |                 <p class="mt-1 max-w-2xl text-sm leading-5 text-gray-500">{{ ctrans('texts.change_plan_description') }}</p> | ||||||
|  | |||||||
| @ -47,6 +47,44 @@ class ExpenseApiTest extends TestCase | |||||||
|         Model::reguard(); |         Model::reguard(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public function testExpensePutWithVendorStatus() | ||||||
|  |     { | ||||||
|  |      | ||||||
|  |      | ||||||
|  |         $data = | ||||||
|  |         [ | ||||||
|  |             'vendor_id' => $this->vendor->hashed_id, | ||||||
|  |             'amount' => 10, | ||||||
|  |             'date' => '2021-10-01', | ||||||
|  |         ]; | ||||||
|  | 
 | ||||||
|  |         $response = $this->withHeaders([ | ||||||
|  |             'X-API-SECRET' => config('ninja.api_secret'), | ||||||
|  |             'X-API-TOKEN' => $this->token, | ||||||
|  |         ])->postJson('/api/v1/expenses', $data); | ||||||
|  | 
 | ||||||
|  |         $arr = $response->json(); | ||||||
|  |         $response->assertStatus(200); | ||||||
|  |      | ||||||
|  | 
 | ||||||
|  |         $this->assertEquals($this->vendor->hashed_id, $arr['data']['vendor_id']); | ||||||
|  | 
 | ||||||
|  |         $data = [ | ||||||
|  |             'payment_date' => now()->format('Y-m-d') | ||||||
|  |         ]; | ||||||
|  | 
 | ||||||
|  |         $response = $this->withHeaders([ | ||||||
|  |                     'X-API-SECRET' => config('ninja.api_secret'), | ||||||
|  |                     'X-API-TOKEN' => $this->token, | ||||||
|  |                 ])->putJson('/api/v1/expenses/'.$arr['data']['id'], $data); | ||||||
|  | 
 | ||||||
|  |         $arr = $response->json(); | ||||||
|  |         $response->assertStatus(200); | ||||||
|  | 
 | ||||||
|  |         $this->assertEquals($this->vendor->hashed_id, $arr['data']['vendor_id']); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public function testTransactionIdClearedOnDelete() |     public function testTransactionIdClearedOnDelete() | ||||||
|     { |     { | ||||||
|         $bi = BankIntegration::factory()->create([ |         $bi = BankIntegration::factory()->create([ | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user