mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-10-31 11:27: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() | ||||
|     { | ||||
|         Invoice::where('next_send_date', '<=', now()->toDateTimeString()) | ||||
|                  ->whereNull('deleted_at') | ||||
|                  ->where('is_deleted', 0) | ||||
|                  ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) | ||||
|                  ->where('balance', '>', 0) | ||||
|                 ->whereNull('invoices.deleted_at') | ||||
|                 ->where('invoices.is_deleted', 0) | ||||
|                 ->whereIn('invoices.status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) | ||||
|                 ->where('invoices.balance', '>', 0) | ||||
|                  ->whereHas('client', function ($query) { | ||||
|                      $query->where('is_deleted', 0) | ||||
|                            ->where('deleted_at', null); | ||||
| @ -73,6 +73,7 @@ class SendRemindersCron extends Command | ||||
|                  ->whereHas('company', function ($query) { | ||||
|                      $query->where('is_disabled', 0); | ||||
|                  }) | ||||
| 
 | ||||
|                  ->with('invitations')->cursor()->each(function ($invoice) { | ||||
|                      if ($invoice->isPayable()) { | ||||
|                          $reminder_template = $invoice->calculateTemplate('invoice'); | ||||
|  | ||||
| @ -320,7 +320,7 @@ class InvoiceFilters extends QueryFilters | ||||
|     { | ||||
|         $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; | ||||
|         } | ||||
| 
 | ||||
|  | ||||
| @ -107,16 +107,16 @@ class InvoiceSumInclusive | ||||
|     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_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_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_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 += $this->total_custom_values; | ||||
| @ -137,21 +137,21 @@ class InvoiceSumInclusive | ||||
|         } | ||||
| 
 | ||||
|         //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) {
 | ||||
|         //     $amount += $this->invoice->custom_surcharge1;
 | ||||
|         // }
 | ||||
|         if(is_numeric($this->invoice->custom_surcharge1) && $this->invoice->custom_surcharge1 > 0 && $this->invoice->custom_surcharge_tax1) { | ||||
|             $amount += $this->invoice->custom_surcharge1; | ||||
|         } | ||||
| 
 | ||||
|         // if(is_numeric($this->invoice->custom_surcharge2) && $this->invoice->custom_surcharge2 > 0 && !$this->invoice->custom_surcharge_tax2) {
 | ||||
|         //     $amount += $this->invoice->custom_surcharge2;
 | ||||
|         // }
 | ||||
|         if(is_numeric($this->invoice->custom_surcharge2) && $this->invoice->custom_surcharge2 > 0 && $this->invoice->custom_surcharge_tax2) { | ||||
|             $amount += $this->invoice->custom_surcharge2; | ||||
|         } | ||||
| 
 | ||||
|         // if(is_numeric($this->invoice->custom_surcharge3) && $this->invoice->custom_surcharge3 > 0 && !$this->invoice->custom_surcharge_tax3) {
 | ||||
|         //     $amount += $this->invoice->custom_surcharge3;
 | ||||
|         // }
 | ||||
|         if(is_numeric($this->invoice->custom_surcharge3) && $this->invoice->custom_surcharge3 > 0 && $this->invoice->custom_surcharge_tax3) { | ||||
|             $amount += $this->invoice->custom_surcharge3; | ||||
|         } | ||||
| 
 | ||||
|         // if(is_numeric($this->invoice->custom_surcharge4) && $this->invoice->custom_surcharge4 > 0 && !$this->invoice->custom_surcharge_tax4) {
 | ||||
|         //     $amount += $this->invoice->custom_surcharge4;
 | ||||
|         // }
 | ||||
|         if(is_numeric($this->invoice->custom_surcharge4) && $this->invoice->custom_surcharge4 > 0 && $this->invoice->custom_surcharge_tax4) { | ||||
|             $amount += $this->invoice->custom_surcharge4; | ||||
|         } | ||||
| 
 | ||||
|         if (is_string($this->invoice->tax_name1) && strlen($this->invoice->tax_name1) > 1) { | ||||
|             $tax = $this->calcInclusiveLineTax($this->invoice->tax_rate1, $amount); | ||||
|  | ||||
| @ -81,14 +81,20 @@ class SearchController extends Controller | ||||
|         $invoices = Invoice::query() | ||||
|                      ->company() | ||||
|                      ->with('client') | ||||
|                      ->where('is_deleted', 0) | ||||
|                      ->whereHas('client', function ($q) { | ||||
|                          $q->where('is_deleted', 0); | ||||
|                      ->where('invoices.is_deleted', 0) | ||||
|                     //  ->whereHas('client', function ($q) {
 | ||||
|                     //      $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) { | ||||
|                          $query->where('user_id', $user->id); | ||||
|                          $query->where('invoices.user_id', $user->id); | ||||
|                      }) | ||||
|                      ->orderBy('id', 'desc') | ||||
|                      ->orderBy('invoices.id', 'desc') | ||||
|                     ->take(3000) | ||||
|                     ->get(); | ||||
| 
 | ||||
|  | ||||
| @ -78,7 +78,9 @@ class StoreInvoiceRequest extends Request | ||||
|         $rules['tax_name3'] = 'bail|sometimes|string|nullable'; | ||||
|         $rules['exchange_rate'] = 'bail|sometimes|numeric'; | ||||
|         $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', 'max:99999999999999'];
 | ||||
|  | ||||
| @ -82,8 +82,8 @@ class UpdateInvoiceRequest extends Request | ||||
| 
 | ||||
|         $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['due_date'] = ['bail', 'sometimes', 'nullable', 'after:partial_due_date', Rule::requiredIf(fn () => strlen($this->partial_due_date) > 1), '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']; | ||||
| 
 | ||||
|         return $rules; | ||||
|     } | ||||
|  | ||||
| @ -66,8 +66,8 @@ class StoreQuoteRequest extends Request | ||||
|         $rules['exchange_rate'] = 'bail|sometimes|numeric'; | ||||
|         $rules['line_items'] = 'array'; | ||||
|         $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['due_date'] = ['bail', 'sometimes', 'nullable', 'after:partial_due_date', Rule::requiredIf(fn () => strlen($this->partial_due_date) > 1), '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']; | ||||
| 
 | ||||
|         return $rules; | ||||
|  | ||||
| @ -65,7 +65,7 @@ class UpdateQuoteRequest extends Request | ||||
| 
 | ||||
|         $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['amount'] = ['sometimes', 'bail', 'numeric', 'max:99999999999999']; | ||||
| 
 | ||||
|  | ||||
| @ -48,12 +48,12 @@ class RecurringInvoicesCron | ||||
|         Auth::logout(); | ||||
| 
 | ||||
|         if (! config('ninja.db.multi_db_enabled')) { | ||||
|             $recurring_invoices = RecurringInvoice::query()->where('status_id', RecurringInvoice::STATUS_ACTIVE) | ||||
|                                                         ->where('is_deleted', false) | ||||
|                                                         ->where('remaining_cycles', '!=', '0') | ||||
|                                                         ->whereNotNull('next_send_date') | ||||
|                                                         ->whereNull('deleted_at') | ||||
|                                                         ->where('next_send_date', '<=', now()->toDateTimeString()) | ||||
|             $recurring_invoices = RecurringInvoice::query()->where('recurring_invoices.status_id', RecurringInvoice::STATUS_ACTIVE) | ||||
|                                                         ->where('recurring_invoices.is_deleted', false) | ||||
|                                                         ->where('recurring_invoices.remaining_cycles', '!=', '0') | ||||
|                                                         ->whereNotNull('recurring_invoices.next_send_date') | ||||
|                                                         ->whereNull('recurring_invoices.deleted_at') | ||||
|                                                         ->where('recurring_invoices.next_send_date', '<=', now()->toDateTimeString()) | ||||
|                                                         ->whereHas('client', function ($query) { | ||||
|                                                             $query->where('is_deleted', 0) | ||||
|                                                                    ->where('deleted_at', null); | ||||
| @ -87,18 +87,27 @@ class RecurringInvoicesCron | ||||
|             foreach (MultiDB::$dbs as $db) { | ||||
|                 MultiDB::setDB($db); | ||||
| 
 | ||||
|                 $recurring_invoices = RecurringInvoice::query()->where('status_id', RecurringInvoice::STATUS_ACTIVE) | ||||
|                                                         ->where('is_deleted', false) | ||||
|                                                         ->where('remaining_cycles', '!=', '0') | ||||
|                                                         ->whereNull('deleted_at') | ||||
|                                                         ->whereNotNull('next_send_date') | ||||
|                                                         ->where('next_send_date', '<=', now()->toDateTimeString()) | ||||
|                                                         ->whereHas('client', function ($query) { | ||||
|                                                             $query->where('is_deleted', 0) | ||||
|                                                                    ->where('deleted_at', null); | ||||
|                 $recurring_invoices = RecurringInvoice::query()->where('recurring_invoices.status_id', RecurringInvoice::STATUS_ACTIVE) | ||||
|                                                         ->where('recurring_invoices.is_deleted', false) | ||||
|                                                         ->where('recurring_invoices.remaining_cycles', '!=', '0') | ||||
|                                                         ->whereNull('recurring_invoices.deleted_at') | ||||
|                                                         ->whereNotNull('recurring_invoices.next_send_date') | ||||
|                                                         ->where('recurring_invoices.next_send_date', '<=', now()->toDateTimeString()) | ||||
|                                                         // ->whereHas('client', function ($query) {
 | ||||
|                                                         //     $query->where('is_deleted', 0)
 | ||||
|                                                         //            ->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) { | ||||
|                                                             $query->where('is_disabled', 0); | ||||
|                                                         ->leftJoin('companies', function ($join) { | ||||
|                                                             $join->on('recurring_invoices.company_id', '=', 'companies.id') | ||||
|                                                                 ->where('companies.is_disabled', 0); | ||||
|                                                         }) | ||||
|                                                         ->with('company') | ||||
|                                                         ->cursor(); | ||||
|  | ||||
| @ -51,20 +51,29 @@ class InvoiceCheckLateWebhook implements ShouldQueue | ||||
|                                   ->pluck('company_id'); | ||||
| 
 | ||||
|             Invoice::query() | ||||
|                  ->where('is_deleted', false) | ||||
|                  ->whereNull('deleted_at') | ||||
|                  ->whereNotNull('due_date') | ||||
|                  ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) | ||||
|                  ->where('balance', '>', 0) | ||||
|                  ->whereIn('company_id', $company_ids) | ||||
|                  ->whereHas('client', function ($query) { | ||||
|                      $query->where('is_deleted', 0) | ||||
|                             ->where('deleted_at', null); | ||||
|                  ->where('invoices.is_deleted', false) | ||||
|                  ->whereNull('invoices.deleted_at') | ||||
|                  ->whereNotNull('invoices.due_date') | ||||
|                  ->whereIn('invoices.status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) | ||||
|                  ->where('invoices.balance', '>', 0) | ||||
|                  ->whereIn('invoices.company_id', $company_ids) | ||||
|                 //  ->whereHas('client', function ($query) {
 | ||||
|                 //      $query->where('is_deleted', 0)
 | ||||
|                 //             ->where('deleted_at', null);
 | ||||
|                 //  })
 | ||||
|                 //     ->whereHas('company', function ($query) {
 | ||||
|                 //         $query->where('is_disabled', 0);
 | ||||
|                 //     })
 | ||||
|                 ->leftJoin('clients', function ($join) { | ||||
|                     $join->on('invoices.client_id', '=', 'clients.id') | ||||
|                         ->where('clients.is_deleted', 0) | ||||
|                         ->whereNull('clients.deleted_at'); | ||||
|                 }) | ||||
|                     ->whereHas('company', function ($query) { | ||||
|                         $query->where('is_disabled', 0); | ||||
|                 ->leftJoin('companies', function ($join) { | ||||
|                     $join->on('invoices.company_id', '=', 'companies.id') | ||||
|                         ->where('companies.is_disabled', 0); | ||||
|                 }) | ||||
|                  ->whereBetween('due_date', [now()->subDay()->startOfDay(), now()->startOfDay()->subSecond()]) | ||||
|                  ->whereBetween('invoices.due_date', [now()->subDay()->startOfDay(), now()->startOfDay()->subSecond()]) | ||||
|                  ->cursor() | ||||
|                  ->each(function ($invoice) { | ||||
|                      (new WebhookHandler(Webhook::EVENT_LATE_INVOICE, $invoice, $invoice->company, 'client'))->handle(); | ||||
| @ -78,20 +87,29 @@ class InvoiceCheckLateWebhook implements ShouldQueue | ||||
|                                       ->pluck('company_id'); | ||||
| 
 | ||||
|                 Invoice::query() | ||||
|                      ->where('is_deleted', false) | ||||
|                      ->whereNull('deleted_at') | ||||
|                      ->whereNotNull('due_date') | ||||
|                      ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) | ||||
|                      ->where('balance', '>', 0) | ||||
|                      ->whereIn('company_id', $company_ids) | ||||
|                      ->whereHas('client', function ($query) { | ||||
|                          $query->where('is_deleted', 0) | ||||
|                                 ->where('deleted_at', null); | ||||
|                      ->where('invoices.is_deleted', false) | ||||
|                      ->whereNull('invoices.deleted_at') | ||||
|                      ->whereNotNull('invoices.due_date') | ||||
|                      ->whereIn('invoices.status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) | ||||
|                      ->where('invoices.balance', '>', 0) | ||||
|                      ->whereIn('invoices.company_id', $company_ids) | ||||
|                     //  ->whereHas('client', function ($query) {
 | ||||
|                     //      $query->where('is_deleted', 0)
 | ||||
|                     //             ->where('deleted_at', null);
 | ||||
|                     //  })
 | ||||
|                     //     ->whereHas('company', function ($query) {
 | ||||
|                     //         $query->where('is_disabled', 0);
 | ||||
|                     //     })
 | ||||
|                     ->leftJoin('clients', function ($join) { | ||||
|                         $join->on('invoices.client_id', '=', 'clients.id') | ||||
|                             ->where('clients.is_deleted', 0) | ||||
|                             ->whereNull('clients.deleted_at'); | ||||
|                     }) | ||||
|                         ->whereHas('company', function ($query) { | ||||
|                             $query->where('is_disabled', 0); | ||||
|                     ->leftJoin('companies', function ($join) { | ||||
|                         $join->on('invoices.company_id', '=', 'companies.id') | ||||
|                             ->where('companies.is_disabled', 0); | ||||
|                     }) | ||||
|                      ->whereBetween('due_date', [now()->subDay()->startOfDay(), now()->startOfDay()->subSecond()]) | ||||
|                      ->whereBetween('invoices.due_date', [now()->subDay()->startOfDay(), now()->startOfDay()->subSecond()]) | ||||
|                      ->cursor() | ||||
|                      ->each(function ($invoice) { | ||||
|                          (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')) { | ||||
|             Quote::query() | ||||
|                  ->where('status_id', Quote::STATUS_SENT) | ||||
|                  ->where('is_deleted', false) | ||||
|                  ->whereNull('deleted_at') | ||||
|                  ->whereNotNull('due_date') | ||||
|                  ->where('quotes.status_id', Quote::STATUS_SENT) | ||||
|                  ->where('quotes.is_deleted', false) | ||||
|                  ->whereNull('quotes.deleted_at') | ||||
|                  ->whereNotNull('quotes.due_date') | ||||
|                  ->whereHas('client', function ($query) { | ||||
|                      $query->where('is_deleted', 0) | ||||
|                             ->where('deleted_at', null); | ||||
| @ -60,8 +60,8 @@ class QuoteCheckExpired implements ShouldQueue | ||||
|                     ->whereHas('company', function ($query) { | ||||
|                         $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() | ||||
|                  ->each(function ($quote) { | ||||
|                      $this->queueExpiredQuoteNotification($quote); | ||||
| @ -71,10 +71,10 @@ class QuoteCheckExpired implements ShouldQueue | ||||
|                 MultiDB::setDB($db); | ||||
| 
 | ||||
|                 Quote::query() | ||||
|                     ->where('status_id', Quote::STATUS_SENT) | ||||
|                     ->where('is_deleted', false) | ||||
|                     ->whereNull('deleted_at') | ||||
|                     ->whereNotNull('due_date') | ||||
|                     ->where('quotes.status_id', Quote::STATUS_SENT) | ||||
|                     ->where('quotes.is_deleted', false) | ||||
|                     ->whereNull('quotes.deleted_at') | ||||
|                     ->whereNotNull('quotes.due_date') | ||||
|                     ->whereHas('client', function ($query) { | ||||
|                         $query->where('is_deleted', 0) | ||||
|                                ->where('deleted_at', null); | ||||
| @ -82,8 +82,8 @@ class QuoteCheckExpired implements ShouldQueue | ||||
|                        ->whereHas('company', function ($query) { | ||||
|                            $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() | ||||
|                     ->each(function ($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')); | ||||
| 
 | ||||
|             Quote::query() | ||||
|                  ->where('is_deleted', 0) | ||||
|                  ->whereIn('status_id', [Invoice::STATUS_SENT]) | ||||
|                  ->whereNull('deleted_at') | ||||
|                  ->where('next_send_date', '<=', now()->toDateTimeString()) | ||||
|                  ->where('quotes.is_deleted', 0) | ||||
|                  ->whereIn('quotes.status_id', [Invoice::STATUS_SENT]) | ||||
|                  ->whereNull('quotes.deleted_at') | ||||
|                  ->where('quotes.next_send_date', '<=', now()->toDateTimeString()) | ||||
|                  ->whereHas('client', function ($query) { | ||||
|                      $query->where('is_deleted', 0) | ||||
|                            ->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')); | ||||
| 
 | ||||
|                 Quote::query() | ||||
|                      ->where('is_deleted', 0) | ||||
|                      ->whereIn('status_id', [Invoice::STATUS_SENT]) | ||||
|                      ->whereNull('deleted_at') | ||||
|                      ->where('next_send_date', '<=', now()->toDateTimeString()) | ||||
|                      ->where('quotes.is_deleted', 0) | ||||
|                      ->whereIn('quotes.status_id', [Invoice::STATUS_SENT]) | ||||
|                      ->whereNull('quotes.deleted_at') | ||||
|                      ->where('quotes.next_send_date', '<=', now()->toDateTimeString()) | ||||
|                      ->whereHas('client', function ($query) { | ||||
|                          $query->where('is_deleted', 0) | ||||
|                                ->where('deleted_at', null); | ||||
| @ -99,6 +99,7 @@ class QuoteReminderJob implements ShouldQueue | ||||
|                      ->whereHas('company', function ($query) { | ||||
|                          $query->where('is_disabled', 0); | ||||
|                      }) | ||||
|                      | ||||
|                      ->with('invitations')->chunk(50, function ($quotes) { | ||||
| 
 | ||||
|                          foreach ($quotes as $quote) { | ||||
|  | ||||
| @ -47,11 +47,10 @@ class ExpenseRepository extends BaseRepository | ||||
|         $user = auth()->user(); | ||||
| 
 | ||||
|         $payment_date = &$data['payment_date']; | ||||
|         $vendor_id = &$data['vendor_id']; | ||||
| 
 | ||||
|         if($payment_date && $payment_date == $expense->payment_date) { | ||||
|             //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; | ||||
|         } | ||||
| 
 | ||||
|  | ||||
| @ -90,15 +90,15 @@ class ARDetailReport extends BaseExport | ||||
|         $this->csv->insertOne($this->buildHeader()); | ||||
| 
 | ||||
|         $query = Invoice::query() | ||||
|                 ->whereIn('invoices.status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) | ||||
|                 ->withTrashed() | ||||
|                 ->whereHas('client', function ($query) { | ||||
|                     $query->where('is_deleted', 0); | ||||
|                 }) | ||||
|                 ->where('company_id', $this->company->id) | ||||
|                 ->where('is_deleted', 0) | ||||
|                 ->where('balance', '>', 0) | ||||
|                 ->orderBy('due_date', 'ASC') | ||||
|                 ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]); | ||||
|                 ->where('invoices.company_id', $this->company->id) | ||||
|                 ->where('invoices.is_deleted', 0) | ||||
|                 ->where('invoices.balance', '>', 0) | ||||
|                 ->orderBy('invoices.due_date', 'ASC'); | ||||
| 
 | ||||
|         $query = $this->addDateRange($query, 'invoices'); | ||||
| 
 | ||||
|  | ||||
| @ -39,7 +39,7 @@ trait PdfMaker | ||||
|             $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 | ||||
|                         ->setHtml($html) | ||||
|  | ||||
| @ -101,18 +101,7 @@ | ||||
|             </dl> | ||||
|         </div> | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|         @if($invoice->subscription && $invoice->subscription?->allow_cancellation) | ||||
|         {{-- INV2-591 --}} | ||||
|         {{-- @if(false) --}} | ||||
|         @if($invoice->subscription && $invoice->subscription?->allow_cancellation && $invoice->status_id == 2) | ||||
|         <div class="bg-white shadow sm:rounded-lg mt-4"> | ||||
|             <div class="px-4 py-5 sm:p-6"> | ||||
|                 <div class="sm:flex sm:items-start sm:justify-between"> | ||||
|  | ||||
| @ -73,7 +73,7 @@ | ||||
|             </div> | ||||
|         @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="px-4 py-5 sm:p-6"> | ||||
|                 <div class="sm:flex sm:items-start sm:justify-between"> | ||||
| @ -92,7 +92,7 @@ | ||||
|         </div> | ||||
|         @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"> | ||||
|                 <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> | ||||
|  | ||||
| @ -47,6 +47,44 @@ class ExpenseApiTest extends TestCase | ||||
|         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() | ||||
|     { | ||||
|         $bi = BankIntegration::factory()->create([ | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user