mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-31 15:42:03 -04:00
commit
d8fdaf054b
@ -11,16 +11,24 @@
|
|||||||
|
|
||||||
namespace App\Console\Commands;
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\DataMapper\InvoiceItem;
|
||||||
|
use App\Events\Invoice\InvoiceWasEmailed;
|
||||||
|
use App\Jobs\Entity\EmailEntity;
|
||||||
use App\Jobs\Ninja\SendReminders;
|
use App\Jobs\Ninja\SendReminders;
|
||||||
|
use App\Jobs\Util\WebhookHandler;
|
||||||
use App\Libraries\MultiDB;
|
use App\Libraries\MultiDB;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use App\Models\Quote;
|
use App\Models\Quote;
|
||||||
use App\Models\Webhook;
|
use App\Models\Webhook;
|
||||||
|
use App\Utils\Ninja;
|
||||||
|
use App\Utils\Traits\MakesDates;
|
||||||
|
use App\Utils\Traits\MakesReminders;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use App\Jobs\Util\WebhookHandler;
|
use Illuminate\Support\Facades\App;
|
||||||
|
|
||||||
class SendRemindersCron extends Command
|
class SendRemindersCron extends Command
|
||||||
{
|
{
|
||||||
|
use MakesReminders, MakesDates;
|
||||||
/**
|
/**
|
||||||
* The name and signature of the console command.
|
* The name and signature of the console command.
|
||||||
*
|
*
|
||||||
@ -52,11 +60,171 @@ class SendRemindersCron extends Command
|
|||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
SendReminders::dispatchNow();
|
|
||||||
|
|
||||||
$this->webHookOverdueInvoices();
|
Invoice::where('next_send_date', '<=', now()->toDateTimeString())
|
||||||
$this->webHookExpiredQuotes();
|
->whereNull('deleted_at')
|
||||||
|
->where('is_deleted', 0)
|
||||||
|
->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
|
||||||
|
->where('balance', '>', 0)
|
||||||
|
->whereHas('client', function ($query) {
|
||||||
|
$query->where('is_deleted',0)
|
||||||
|
->where('deleted_at', NULL);
|
||||||
|
})
|
||||||
|
->whereHas('company', function ($query) {
|
||||||
|
$query->where('is_disabled',0);
|
||||||
|
})
|
||||||
|
->with('invitations')->cursor()->each(function ($invoice) {
|
||||||
|
|
||||||
|
if ($invoice->isPayable()) {
|
||||||
|
$reminder_template = $invoice->calculateTemplate('invoice');
|
||||||
|
$invoice->service()->touchReminder($reminder_template)->save();
|
||||||
|
$invoice = $this->calcLateFee($invoice, $reminder_template);
|
||||||
|
|
||||||
|
//check if this reminder needs to be emailed
|
||||||
|
if(in_array($reminder_template, ['reminder1','reminder2','reminder3']) && $invoice->client->getSetting("enable_".$reminder_template))
|
||||||
|
{
|
||||||
|
$invoice->invitations->each(function ($invitation) use ($invoice, $reminder_template) {
|
||||||
|
EmailEntity::dispatch($invitation, $invitation->company, $reminder_template);
|
||||||
|
nlog("Firing reminder email for invoice {$invoice->number}");
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($invoice->invitations->count() > 0) {
|
||||||
|
event(new InvoiceWasEmailed($invoice->invitations->first(), $invoice->company, Ninja::eventVars(), $reminder_template));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$invoice->service()->setReminder()->save();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$invoice->next_send_date = null;
|
||||||
|
$invoice->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// SendReminders::dispatchNow();
|
||||||
|
|
||||||
|
// $this->webHookOverdueInvoices();
|
||||||
|
// $this->webHookExpiredQuotes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function calcLateFee($invoice, $template) :Invoice
|
||||||
|
{
|
||||||
|
$late_fee_amount = 0;
|
||||||
|
$late_fee_percent = 0;
|
||||||
|
|
||||||
|
switch ($template) {
|
||||||
|
case 'reminder1':
|
||||||
|
$late_fee_amount = $invoice->client->getSetting('late_fee_amount1');
|
||||||
|
$late_fee_percent = $invoice->client->getSetting('late_fee_percent1');
|
||||||
|
break;
|
||||||
|
case 'reminder2':
|
||||||
|
$late_fee_amount = $invoice->client->getSetting('late_fee_amount2');
|
||||||
|
$late_fee_percent = $invoice->client->getSetting('late_fee_percent2');
|
||||||
|
break;
|
||||||
|
case 'reminder3':
|
||||||
|
$late_fee_amount = $invoice->client->getSetting('late_fee_amount3');
|
||||||
|
$late_fee_percent = $invoice->client->getSetting('late_fee_percent3');
|
||||||
|
break;
|
||||||
|
case 'endless_reminder':
|
||||||
|
$late_fee_amount = $invoice->client->getSetting('late_fee_endless_amount');
|
||||||
|
$late_fee_percent = $invoice->client->getSetting('late_fee_endless_percent');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$late_fee_amount = 0;
|
||||||
|
$late_fee_percent = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->setLateFee($invoice, $late_fee_amount, $late_fee_percent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies the late fee to the invoice line items
|
||||||
|
*
|
||||||
|
* @param Invoice $invoice
|
||||||
|
* @param float $amount The fee amount
|
||||||
|
* @param float $percent The fee percentage amount
|
||||||
|
*
|
||||||
|
* @return Invoice
|
||||||
|
*/
|
||||||
|
private function setLateFee($invoice, $amount, $percent) :Invoice
|
||||||
|
{
|
||||||
|
|
||||||
|
App::forgetInstance('translator');
|
||||||
|
$t = app('translator');
|
||||||
|
$t->replace(Ninja::transformTranslations($invoice->client->getMergedSettings()));
|
||||||
|
App::setLocale($invoice->client->locale());
|
||||||
|
|
||||||
|
$temp_invoice_balance = $invoice->balance;
|
||||||
|
|
||||||
|
if ($amount <= 0 && $percent <= 0) {
|
||||||
|
return $invoice;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fee = $amount;
|
||||||
|
|
||||||
|
if ($invoice->partial > 0) {
|
||||||
|
$fee += round($invoice->partial * $percent / 100, 2);
|
||||||
|
} else {
|
||||||
|
$fee += round($invoice->balance * $percent / 100, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
$invoice_item = new InvoiceItem;
|
||||||
|
$invoice_item->type_id = '5';
|
||||||
|
$invoice_item->product_key = trans('texts.fee');
|
||||||
|
$invoice_item->notes = ctrans('texts.late_fee_added', ['date' => $this->translateDate(now()->startOfDay(), $invoice->client->date_format(), $invoice->client->locale())]);
|
||||||
|
$invoice_item->quantity = 1;
|
||||||
|
$invoice_item->cost = $fee;
|
||||||
|
|
||||||
|
$invoice_items = $invoice->line_items;
|
||||||
|
$invoice_items[] = $invoice_item;
|
||||||
|
|
||||||
|
$invoice->line_items = $invoice_items;
|
||||||
|
|
||||||
|
/**Refresh Invoice values*/
|
||||||
|
$invoice->calc()->getInvoice()->save();
|
||||||
|
$invoice->fresh();
|
||||||
|
$invoice->service()->deletePdf();
|
||||||
|
|
||||||
|
/* Refresh the client here to ensure the balance is fresh */
|
||||||
|
$client = $invoice->client;
|
||||||
|
$client = $client->fresh();
|
||||||
|
|
||||||
|
nlog("adjusting client balance and invoice balance by ". ($invoice->balance - $temp_invoice_balance));
|
||||||
|
$client->service()->updateBalance($invoice->balance - $temp_invoice_balance)->save();
|
||||||
|
$invoice->ledger()->updateInvoiceBalance($invoice->balance - $temp_invoice_balance, "Late Fee Adjustment for invoice {$invoice->number}");
|
||||||
|
|
||||||
|
return $invoice;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private function webHookOverdueInvoices()
|
private function webHookOverdueInvoices()
|
||||||
{
|
{
|
||||||
|
@ -39,7 +39,7 @@ class StatementController extends Controller
|
|||||||
public function raw(ShowStatementRequest $request)
|
public function raw(ShowStatementRequest $request)
|
||||||
{
|
{
|
||||||
$pdf = $request->client()->service()->statement(
|
$pdf = $request->client()->service()->statement(
|
||||||
$request->only(['start_date', 'end_date', 'show_payments_table', 'show_aging_table'])
|
$request->only(['start_date', 'end_date', 'show_payments_table', 'show_aging_table', 'status'])
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($pdf && $request->query('download')) {
|
if ($pdf && $request->query('download')) {
|
||||||
|
@ -111,13 +111,13 @@ class ClientStatementController extends BaseController
|
|||||||
public function statement(CreateStatementRequest $request)
|
public function statement(CreateStatementRequest $request)
|
||||||
{
|
{
|
||||||
$pdf = $request->client()->service()->statement(
|
$pdf = $request->client()->service()->statement(
|
||||||
$request->only(['start_date', 'end_date', 'show_payments_table', 'show_aging_table'])
|
$request->only(['start_date', 'end_date', 'show_payments_table', 'show_aging_table', 'status'])
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($pdf) {
|
if ($pdf) {
|
||||||
return response()->streamDownload(function () use ($pdf) {
|
return response()->streamDownload(function () use ($pdf) {
|
||||||
echo $pdf;
|
echo $pdf;
|
||||||
}, 'statement.pdf', ['Content-Type' => 'application/pdf']);
|
}, ctrans('texts.statement') . '.pdf', ['Content-Type' => 'application/pdf']);
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json(['message' => 'Something went wrong. Please check logs.']);
|
return response()->json(['message' => 'Something went wrong. Please check logs.']);
|
||||||
|
@ -141,7 +141,8 @@ class RequiredClientInfo extends Component
|
|||||||
$_field = $this->mappings[$field['name']];
|
$_field = $this->mappings[$field['name']];
|
||||||
|
|
||||||
if (Str::startsWith($field['name'], 'client_')) {
|
if (Str::startsWith($field['name'], 'client_')) {
|
||||||
if (empty($this->contact->client->{$_field}) || is_null($this->contact->client->{$_field}) || $this->contact->client->{$_field} == 840) {
|
if (empty($this->contact->client->{$_field}) || is_null($this->contact->client->{$_field})) {
|
||||||
|
// if (empty($this->contact->client->{$_field}) || is_null($this->contact->client->{$_field}) || $this->contact->client->{$_field} == 840) {
|
||||||
$this->show_form = true;
|
$this->show_form = true;
|
||||||
} else {
|
} else {
|
||||||
$this->fields[$index]['filled'] = true;
|
$this->fields[$index]['filled'] = true;
|
||||||
@ -149,7 +150,8 @@ class RequiredClientInfo extends Component
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Str::startsWith($field['name'], 'contact_')) {
|
if (Str::startsWith($field['name'], 'contact_')) {
|
||||||
if ((empty($this->contact->{$_field}) || is_null($this->contact->{$_field})) || $this->contact->client->{$_field} == 840) {
|
if (empty($this->contact->client->{$_field}) || is_null($this->contact->client->{$_field})) {
|
||||||
|
// if ((empty($this->contact->{$_field}) || is_null($this->contact->{$_field})) || $this->contact->client->{$_field} == 840) {
|
||||||
$this->show_form = true;
|
$this->show_form = true;
|
||||||
} else {
|
} else {
|
||||||
$this->fields[$index]['filled'] = true;
|
$this->fields[$index]['filled'] = true;
|
||||||
|
@ -44,7 +44,6 @@ class ShowStatementRequest extends FormRequest
|
|||||||
|
|
||||||
public function client(): Client
|
public function client(): Client
|
||||||
{
|
{
|
||||||
// return Client::withTrashed()->without('contacts.company', 'documents', 'gateway_tokens')->where('id', auth('contact')->user()->client_id)->first();
|
|
||||||
return auth('contact')->user()->client;
|
return auth('contact')->user()->client;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ class CreateStatementRequest extends Request
|
|||||||
'client_id' => 'bail|required|exists:clients,id,company_id,' . auth()->user()->company()->id,
|
'client_id' => 'bail|required|exists:clients,id,company_id,' . auth()->user()->company()->id,
|
||||||
'show_payments_table' => 'boolean',
|
'show_payments_table' => 'boolean',
|
||||||
'show_aging_table' => 'boolean',
|
'show_aging_table' => 'boolean',
|
||||||
|
'status' => 'string',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
namespace App\Jobs\Entity;
|
namespace App\Jobs\Entity;
|
||||||
|
|
||||||
use App\Exceptions\FilePermissionsFailure;
|
use App\Exceptions\FilePermissionsFailure;
|
||||||
|
use App\Libraries\MultiDB;
|
||||||
use App\Models\Account;
|
use App\Models\Account;
|
||||||
use App\Models\Credit;
|
use App\Models\Credit;
|
||||||
use App\Models\CreditInvitation;
|
use App\Models\CreditInvitation;
|
||||||
@ -101,8 +102,7 @@ class CreateEntityPdf implements ShouldQueue
|
|||||||
|
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
$start = microtime(true);
|
MultiDB::setDb($this->company->db);
|
||||||
// nlog("Start ". $start);
|
|
||||||
|
|
||||||
/* Forget the singleton*/
|
/* Forget the singleton*/
|
||||||
App::forgetInstance('translator');
|
App::forgetInstance('translator');
|
||||||
@ -204,9 +204,9 @@ class CreateEntityPdf implements ShouldQueue
|
|||||||
try{
|
try{
|
||||||
|
|
||||||
if(!Storage::disk($this->disk)->exists($path))
|
if(!Storage::disk($this->disk)->exists($path))
|
||||||
Storage::disk($this->disk)->makeDirectory($path, 0775);
|
|
||||||
|
|
||||||
Storage::disk($this->disk)->put($file_path, $pdf);
|
Storage::disk($this->disk)->makeDirectory($path, 0775);
|
||||||
|
Storage::disk($this->disk)->put($file_path, $pdf, 'public');
|
||||||
|
|
||||||
}
|
}
|
||||||
catch(\Exception $e)
|
catch(\Exception $e)
|
||||||
|
@ -227,12 +227,36 @@ class Statement
|
|||||||
->where('is_deleted', false)
|
->where('is_deleted', false)
|
||||||
->where('company_id', $this->client->company_id)
|
->where('company_id', $this->client->company_id)
|
||||||
->where('client_id', $this->client->id)
|
->where('client_id', $this->client->id)
|
||||||
->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL, Invoice::STATUS_PAID])
|
->whereIn('status_id', $this->invoiceStatuses())
|
||||||
->whereBetween('date', [Carbon::parse($this->options['start_date']), Carbon::parse($this->options['end_date'])])
|
->whereBetween('date', [Carbon::parse($this->options['start_date']), Carbon::parse($this->options['end_date'])])
|
||||||
->orderBy('number', 'ASC')
|
->orderBy('date', 'ASC')
|
||||||
->cursor();
|
->cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function invoiceStatuses() :array
|
||||||
|
{
|
||||||
|
$status = 'all';
|
||||||
|
nlog($this->options);
|
||||||
|
if(array_key_exists('status', $this->options))
|
||||||
|
$status = $this->options['status'];
|
||||||
|
|
||||||
|
switch ($status) {
|
||||||
|
case 'all':
|
||||||
|
return [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL, Invoice::STATUS_PAID];
|
||||||
|
break;
|
||||||
|
case 'paid':
|
||||||
|
return [Invoice::STATUS_PARTIAL, Invoice::STATUS_PAID];
|
||||||
|
break;
|
||||||
|
case 'unpaid':
|
||||||
|
return [Invoice::STATUS_SENT];
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL, Invoice::STATUS_PAID];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The collection of payments for the statement.
|
* The collection of payments for the statement.
|
||||||
*
|
*
|
||||||
@ -247,7 +271,7 @@ class Statement
|
|||||||
->where('client_id', $this->client->id)
|
->where('client_id', $this->client->id)
|
||||||
->whereIn('status_id', [Payment::STATUS_COMPLETED, Payment::STATUS_PARTIALLY_REFUNDED, Payment::STATUS_REFUNDED])
|
->whereIn('status_id', [Payment::STATUS_COMPLETED, Payment::STATUS_PARTIALLY_REFUNDED, Payment::STATUS_REFUNDED])
|
||||||
->whereBetween('date', [Carbon::parse($this->options['start_date']), Carbon::parse($this->options['end_date'])])
|
->whereBetween('date', [Carbon::parse($this->options['start_date']), Carbon::parse($this->options['end_date'])])
|
||||||
->orderBy('number', 'ASC')
|
->orderBy('date', 'ASC')
|
||||||
->cursor();
|
->cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,11 +108,9 @@ class GenerateDeliveryNote
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!Storage::disk($this->disk)->exists($this->invoice->client->invoice_filepath($invitation)))
|
if(!Storage::disk($this->disk)->exists($this->invoice->client->invoice_filepath($invitation)))
|
||||||
|
|
||||||
Storage::disk($this->disk)->makeDirectory($this->invoice->client->invoice_filepath($invitation), 0775);
|
Storage::disk($this->disk)->makeDirectory($this->invoice->client->invoice_filepath($invitation), 0775);
|
||||||
|
Storage::disk($this->disk)->put($file_path, $pdf, 'public');
|
||||||
Storage::disk($this->disk)->put($file_path, $pdf);
|
|
||||||
|
|
||||||
//return Storage::disk($this->disk)->path($file_path);
|
|
||||||
|
|
||||||
return $file_path;
|
return $file_path;
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ class InvoiceService
|
|||||||
|
|
||||||
$this->invoice->balance += $balance_adjustment;
|
$this->invoice->balance += $balance_adjustment;
|
||||||
|
|
||||||
if ($this->invoice->balance == 0 && !$is_draft) {
|
if (round($this->invoice->balance,2) == 0 && !$is_draft) {
|
||||||
$this->invoice->status_id = Invoice::STATUS_PAID;
|
$this->invoice->status_id = Invoice::STATUS_PAID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,7 +285,7 @@ class InvoiceService
|
|||||||
|
|
||||||
public function setCalculatedStatus()
|
public function setCalculatedStatus()
|
||||||
{
|
{
|
||||||
if ((int)$this->invoice->balance == 0) {
|
if (round($this->invoice->balance,2) == 0) {
|
||||||
$this->setStatus(Invoice::STATUS_PAID);
|
$this->setStatus(Invoice::STATUS_PAID);
|
||||||
} elseif ($this->invoice->balance > 0 && $this->invoice->balance < $this->invoice->amount) {
|
} elseif ($this->invoice->balance > 0 && $this->invoice->balance < $this->invoice->amount) {
|
||||||
$this->setStatus(Invoice::STATUS_PARTIAL);
|
$this->setStatus(Invoice::STATUS_PARTIAL);
|
||||||
@ -299,7 +299,7 @@ class InvoiceService
|
|||||||
if($this->invoice->status_id == Invoice::STATUS_DRAFT)
|
if($this->invoice->status_id == Invoice::STATUS_DRAFT)
|
||||||
return $this;
|
return $this;
|
||||||
|
|
||||||
if($this->invoice->balance == 0){
|
if(round($this->invoice->balance,2) == 0){
|
||||||
$this->invoice->status_id = Invoice::STATUS_PAID;
|
$this->invoice->status_id = Invoice::STATUS_PAID;
|
||||||
}
|
}
|
||||||
elseif ($this->invoice->balance > 0 && $this->invoice->balance < $this->invoice->amount) {
|
elseif ($this->invoice->balance > 0 && $this->invoice->balance < $this->invoice->amount) {
|
||||||
|
@ -77,7 +77,7 @@ class AccountTransformer extends EntityTransformer
|
|||||||
'report_errors' => (bool) $account->report_errors,
|
'report_errors' => (bool) $account->report_errors,
|
||||||
'debug_enabled' => (bool) config('ninja.debug_enabled'),
|
'debug_enabled' => (bool) config('ninja.debug_enabled'),
|
||||||
'is_docker' => (bool) config('ninja.is_docker'),
|
'is_docker' => (bool) config('ninja.is_docker'),
|
||||||
'is_scheduler_running' => (bool) $account->is_scheduler_running,
|
'is_scheduler_running' => Ninja::isHosted() ? (bool) true : (bool) $account->is_scheduler_running, //force true for hosted 03/01/2022
|
||||||
'default_company_id' => (string) $this->encodePrimaryKey($account->default_company_id),
|
'default_company_id' => (string) $this->encodePrimaryKey($account->default_company_id),
|
||||||
'disable_auto_update' => (bool) config('ninja.disable_auto_update'),
|
'disable_auto_update' => (bool) config('ninja.disable_auto_update'),
|
||||||
'emails_sent' => (int) $account->emailsSent(),
|
'emails_sent' => (int) $account->emailsSent(),
|
||||||
|
@ -54,7 +54,21 @@ return [
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'asset_url' => env('ASSETS_URL', config('app.url')),
|
'asset_url' => null,
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Livewire App URL
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This value should be used if livewire assets are served from CDN.
|
||||||
|
| Livewire will communicate with an app through this url.
|
||||||
|
|
|
||||||
|
| Examples: "https://my-app.com", "myurl.com/app".
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'app_url' => null,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
@ -101,7 +115,7 @@ return [
|
|||||||
|
|
|
|
||||||
| This value sets the path to the Livewire manifest file.
|
| This value sets the path to the Livewire manifest file.
|
||||||
| The default should work for most cases (which is
|
| The default should work for most cases (which is
|
||||||
| "<app_root>/bootstrap/cache/livewire-components.php)", but for specific
|
| "<app_root>/bootstrap/cache/livewire-components.php"), but for specific
|
||||||
| cases like when hosting on Laravel Vapor, it could be set to a different value.
|
| cases like when hosting on Laravel Vapor, it could be set to a different value.
|
||||||
|
|
|
|
||||||
| Example: for Laravel Vapor, it would be "/tmp/storage/bootstrap/cache/livewire-components.php".
|
| Example: for Laravel Vapor, it would be "/tmp/storage/bootstrap/cache/livewire-components.php".
|
||||||
@ -110,4 +124,35 @@ return [
|
|||||||
|
|
||||||
'manifest_path' => null,
|
'manifest_path' => null,
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Back Button Cache
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This value determines whether the back button cache will be used on pages
|
||||||
|
| that contain Livewire. By disabling back button cache, it ensures that
|
||||||
|
| the back button shows the correct state of components, instead of
|
||||||
|
| potentially stale, cached data.
|
||||||
|
|
|
||||||
|
| Setting it to "false" (default) will disable back button cache.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'back_button_cache' => false,
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Render On Redirect
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This value determines whether Livewire will render before it's redirected
|
||||||
|
| or not. Setting it to "false" (default) will mean the render method is
|
||||||
|
| skipped when redirecting. And "true" will mean the render method is
|
||||||
|
| run before redirecting. Browsers bfcache can store a potentially
|
||||||
|
| stale view if render is skipped on redirect.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'render_on_redirect' => false,
|
||||||
|
|
||||||
];
|
];
|
||||||
|
10431
package-lock.json
generated
10431
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
2
public/js/clients/statements/view.js
vendored
2
public/js/clients/statements/view.js
vendored
@ -1,2 +1,2 @@
|
|||||||
/*! For license information please see view.js.LICENSE.txt */
|
/*! For license information please see view.js.LICENSE.txt */
|
||||||
(()=>{function e(e,t){for(var a=0;a<t.length;a++){var n=t[a];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}(new(function(){function t(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),this.url=new URL(document.querySelector("meta[name=pdf-url]").content),this.startDate="",this.endDate="",this.showPaymentsTable=!1,this.showAgingTable=!1}var a,n,r;return a=t,(n=[{key:"bindEventListeners",value:function(){var e=this;["#date-from","#date-to","#show-payments-table","#show-aging-table"].forEach((function(t){document.querySelector(t).addEventListener("change",(function(t){return e.handleValueChange(t)}))}))}},{key:"handleValueChange",value:function(e){"checkbox"===e.target.type?this[e.target.dataset.field]=e.target.checked:this[e.target.dataset.field]=e.target.value,this.updatePdf()}},{key:"composedUrl",get:function(){return this.url.search="",this.startDate.length>0&&this.url.searchParams.append("start_date",this.startDate),this.endDate.length>0&&this.url.searchParams.append("end_date",this.endDate),this.url.searchParams.append("show_payments_table",+this.showPaymentsTable),this.url.searchParams.append("show_aging_table",+this.showAgingTable),this.url.href}},{key:"updatePdf",value:function(){document.querySelector("meta[name=pdf-url]").content=this.composedUrl;var e=document.querySelector("#pdf-iframe");e&&(e.src=this.composedUrl),document.querySelector("meta[name=pdf-url]").dispatchEvent(new Event("change"))}},{key:"handle",value:function(){var e=this;this.bindEventListeners(),document.querySelector("#pdf-download").addEventListener("click",(function(){var t=new URL(e.composedUrl);t.searchParams.append("download",1),window.location.href=t.href}))}}])&&e(a.prototype,n),r&&e(a,r),t}())).handle()})();
|
(()=>{function e(e,t){for(var a=0;a<t.length;a++){var n=t[a];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}(new(function(){function t(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),this.url=new URL(document.querySelector("meta[name=pdf-url]").content),this.startDate="",this.endDate="",this.showPaymentsTable=!1,this.showAgingTable=!1,this.status=""}var a,n,r;return a=t,(n=[{key:"bindEventListeners",value:function(){var e=this;["#date-from","#date-to","#show-payments-table","#show-aging-table","#status"].forEach((function(t){document.querySelector(t).addEventListener("change",(function(t){return e.handleValueChange(t)}))}))}},{key:"handleValueChange",value:function(e){"checkbox"===e.target.type?this[e.target.dataset.field]=e.target.checked:this[e.target.dataset.field]=e.target.value,this.updatePdf()}},{key:"composedUrl",get:function(){return this.url.search="",this.startDate.length>0&&this.url.searchParams.append("start_date",this.startDate),this.endDate.length>0&&this.url.searchParams.append("end_date",this.endDate),this.url.searchParams.append("status",document.getElementById("status").value),this.url.searchParams.append("show_payments_table",+this.showPaymentsTable),this.url.searchParams.append("show_aging_table",+this.showAgingTable),this.url.href}},{key:"updatePdf",value:function(){document.querySelector("meta[name=pdf-url]").content=this.composedUrl;var e=document.querySelector("#pdf-iframe");e&&(e.src=this.composedUrl),document.querySelector("meta[name=pdf-url]").dispatchEvent(new Event("change"))}},{key:"handle",value:function(){var e=this;this.bindEventListeners(),document.querySelector("#pdf-download").addEventListener("click",(function(){var t=new URL(e.composedUrl);t.searchParams.append("download",1),window.location.href=t.href}))}}])&&e(a.prototype,n),r&&e(a,r),t}())).handle()})();
|
@ -25,7 +25,7 @@
|
|||||||
"/js/clients/payments/eway-credit-card.js": "/js/clients/payments/eway-credit-card.js?id=ff17e039dd15d505448f",
|
"/js/clients/payments/eway-credit-card.js": "/js/clients/payments/eway-credit-card.js?id=ff17e039dd15d505448f",
|
||||||
"/js/clients/payment_methods/braintree-ach.js": "/js/clients/payment_methods/braintree-ach.js?id=656ad159838b726969f5",
|
"/js/clients/payment_methods/braintree-ach.js": "/js/clients/payment_methods/braintree-ach.js?id=656ad159838b726969f5",
|
||||||
"/js/clients/payments/square-credit-card.js": "/js/clients/payments/square-credit-card.js?id=8f05ce6bd2d6cae7e5f2",
|
"/js/clients/payments/square-credit-card.js": "/js/clients/payments/square-credit-card.js?id=8f05ce6bd2d6cae7e5f2",
|
||||||
"/js/clients/statements/view.js": "/js/clients/statements/view.js?id=ea3db0c04b4372f76735",
|
"/js/clients/statements/view.js": "/js/clients/statements/view.js?id=4ed4c8a09803ddd0a9a7",
|
||||||
"/js/clients/payments/razorpay-aio.js": "/js/clients/payments/razorpay-aio.js?id=c36ab5621413ef1de7c8",
|
"/js/clients/payments/razorpay-aio.js": "/js/clients/payments/razorpay-aio.js?id=c36ab5621413ef1de7c8",
|
||||||
"/js/clients/payments/stripe-sepa.js": "/js/clients/payments/stripe-sepa.js?id=cbd7bb4c483ca75333f4",
|
"/js/clients/payments/stripe-sepa.js": "/js/clients/payments/stripe-sepa.js?id=cbd7bb4c483ca75333f4",
|
||||||
"/js/clients/payment_methods/authorize-checkout-card.js": "/js/clients/payment_methods/authorize-checkout-card.js?id=61becda97682c7909f29",
|
"/js/clients/payment_methods/authorize-checkout-card.js": "/js/clients/payment_methods/authorize-checkout-card.js?id=61becda97682c7909f29",
|
||||||
|
2
public/vendor/livewire/livewire.js
vendored
2
public/vendor/livewire/livewire.js
vendored
File diff suppressed because one or more lines are too long
2
public/vendor/livewire/livewire.js.map
vendored
2
public/vendor/livewire/livewire.js.map
vendored
File diff suppressed because one or more lines are too long
2
public/vendor/livewire/manifest.json
vendored
2
public/vendor/livewire/manifest.json
vendored
@ -1 +1 @@
|
|||||||
{"/livewire.js":"/livewire.js?id=ece4c4ab4b746f6f1739"}
|
{"/livewire.js":"/livewire.js?id=f092ba91a90e56843ffc"}
|
4
resources/js/clients/statements/view.js
vendored
4
resources/js/clients/statements/view.js
vendored
@ -17,6 +17,7 @@ class Statement {
|
|||||||
this.endDate = '';
|
this.endDate = '';
|
||||||
this.showPaymentsTable = false;
|
this.showPaymentsTable = false;
|
||||||
this.showAgingTable = false;
|
this.showAgingTable = false;
|
||||||
|
this.status = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
bindEventListeners() {
|
bindEventListeners() {
|
||||||
@ -25,6 +26,7 @@ class Statement {
|
|||||||
'#date-to',
|
'#date-to',
|
||||||
'#show-payments-table',
|
'#show-payments-table',
|
||||||
'#show-aging-table',
|
'#show-aging-table',
|
||||||
|
'#status',
|
||||||
].forEach((selector) => {
|
].forEach((selector) => {
|
||||||
document
|
document
|
||||||
.querySelector(selector)
|
.querySelector(selector)
|
||||||
@ -55,6 +57,8 @@ class Statement {
|
|||||||
this.url.searchParams.append('end_date', this.endDate);
|
this.url.searchParams.append('end_date', this.endDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.url.searchParams.append('status', document.getElementById("status").value);
|
||||||
|
|
||||||
this.url.searchParams.append(
|
this.url.searchParams.append(
|
||||||
'show_payments_table',
|
'show_payments_table',
|
||||||
+this.showPaymentsTable
|
+this.showPaymentsTable
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
@if(!array_key_exists('filled', $field))
|
@if(!array_key_exists('filled', $field))
|
||||||
@component('portal.ninja2020.components.general.card-element', ['title' => $field['label']])
|
@component('portal.ninja2020.components.general.card-element', ['title' => $field['label']])
|
||||||
@if($field['name'] == 'client_country_id' || $field['name'] == 'client_shipping_country_id')
|
@if($field['name'] == 'client_country_id' || $field['name'] == 'client_shipping_country_id')
|
||||||
<select id="country" class="input w-full form-select" name="{{ $field['name'] }}">
|
<select id="client_country" class="input w-full form-select" name="{{ $field['name'] }}">
|
||||||
<option value="none"></option>
|
<option value="none"></option>
|
||||||
|
|
||||||
@foreach($countries as $country)
|
@foreach($countries as $country)
|
||||||
|
@ -21,6 +21,15 @@
|
|||||||
</label>
|
</label>
|
||||||
</div> <!-- End date range -->
|
</div> <!-- End date range -->
|
||||||
|
|
||||||
|
<label for="show_status" class="block w-4/5 flex items-center mr-4">
|
||||||
|
<span class="mr-2">{{ ctrans('texts.status') }}:</span>
|
||||||
|
<select id="status" name="status" class="input w-full form-select">
|
||||||
|
<option value="all">{{ ctrans('texts.all')}} </option>
|
||||||
|
<option value="paid">{{ ctrans('texts.paid')}} </option>
|
||||||
|
<option value="unpaid">{{ ctrans('texts.unpaid')}} </option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
|
||||||
<label for="show_payments" class="block flex items-center mr-4 mt-4 md:mt-0">
|
<label for="show_payments" class="block flex items-center mr-4 mt-4 md:mt-0">
|
||||||
<input id="show-payments-table" type="checkbox" data-field="showPaymentsTable" class="form-checkbox" autocomplete="off">
|
<input id="show-payments-table" type="checkbox" data-field="showPaymentsTable" class="form-checkbox" autocomplete="off">
|
||||||
<span class="ml-2">{{ ctrans('texts.show_payments') }}</span>
|
<span class="ml-2">{{ ctrans('texts.show_payments') }}</span>
|
||||||
@ -30,6 +39,7 @@
|
|||||||
<input id="show-aging-table" type="checkbox" data-field="showAgingTable" class="form-checkbox" autocomplete="off">
|
<input id="show-aging-table" type="checkbox" data-field="showAgingTable" class="form-checkbox" autocomplete="off">
|
||||||
<span class="ml-2">{{ ctrans('texts.show_aging') }}</span>
|
<span class="ml-2">{{ ctrans('texts.show_aging') }}</span>
|
||||||
</label> <!-- End show aging checkbox -->
|
</label> <!-- End show aging checkbox -->
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<button onclick="setTimeout(() => this.disabled = true, 0); setTimeout(() => this.disabled = false, 5000); return true;" id="pdf-download" class="button button-primary bg-primary mt-4 md:mt-0">{{ ctrans('texts.download') }}</button>
|
<button onclick="setTimeout(() => this.disabled = true, 0); setTimeout(() => this.disabled = false, 5000); return true;" id="pdf-download" class="button button-primary bg-primary mt-4 md:mt-0">{{ ctrans('texts.download') }}</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -8,16 +8,28 @@
|
|||||||
<span class="page-link">@lang('pagination.previous')</span>
|
<span class="page-link">@lang('pagination.previous')</span>
|
||||||
</li>
|
</li>
|
||||||
@else
|
@else
|
||||||
<li class="page-item">
|
@if(method_exists($paginator,'getCursorName'))
|
||||||
<button type="button" class="page-link" wire:click="previousPage" wire:loading.attr="disabled" rel="prev">@lang('pagination.previous')</button>
|
<li class="page-item">
|
||||||
</li>
|
<button dusk="previousPage{{ $paginator->getCursorName() == 'page' ? '' : '.' . $paginator->getPageName() }}" type="button" class="page-link" wire:click="setPage('{{$paginator->previousCursor()->encode()}}','{{ $paginator->getCursorName() }}')" wire:loading.attr="disabled" rel="prev">@lang('pagination.previous')</button>
|
||||||
|
</li>
|
||||||
|
@else
|
||||||
|
<li class="page-item">
|
||||||
|
<button type="button" dusk="previousPage{{ $paginator->getPageName() == 'page' ? '' : '.' . $paginator->getPageName() }}" class="page-link" wire:click="previousPage('{{ $paginator->getPageName() }}')" wire:loading.attr="disabled" rel="prev">@lang('pagination.previous')</button>
|
||||||
|
</li>
|
||||||
|
@endif
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
{{-- Next Page Link --}}
|
{{-- Next Page Link --}}
|
||||||
@if ($paginator->hasMorePages())
|
@if ($paginator->hasMorePages())
|
||||||
<li class="page-item">
|
@if(method_exists($paginator,'getCursorName'))
|
||||||
<button type="button" class="page-link" wire:click="nextPage" wire:loading.attr="disabled" rel="next">@lang('pagination.next')</button>
|
<li class="page-item">
|
||||||
</li>
|
<button dusk="nextPage{{ $paginator->getCursorName() == 'page' ? '' : '.' . $paginator->getPageName() }}" type="button" class="page-link" wire:click="setPage('{{$paginator->nextCursor()->encode()}}','{{ $paginator->getCursorName() }}')" wire:loading.attr="disabled" rel="next">@lang('pagination.next')</button>
|
||||||
|
</li>
|
||||||
|
@else
|
||||||
|
<li class="page-item">
|
||||||
|
<button type="button" dusk="nextPage{{ $paginator->getPageName() == 'page' ? '' : '.' . $paginator->getPageName() }}" class="page-link" wire:click="nextPage('{{ $paginator->getPageName() }}')" wire:loading.attr="disabled" rel="next">@lang('pagination.next')</button>
|
||||||
|
</li>
|
||||||
|
@endif
|
||||||
@else
|
@else
|
||||||
<li class="page-item disabled" aria-disabled="true">
|
<li class="page-item disabled" aria-disabled="true">
|
||||||
<span class="page-link">@lang('pagination.next')</span>
|
<span class="page-link">@lang('pagination.next')</span>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user