merge v5-develop

This commit is contained in:
David Bomba 2023-02-21 10:59:11 +11:00
parent 19fdd9e96e
commit e3949c0479
3 changed files with 235 additions and 272 deletions

View File

@ -4193,7 +4193,7 @@
*/ */
public static function lock($name, $seconds = 0, $owner = null) public static function lock($name, $seconds = 0, $owner = null)
{ {
/** @var \Illuminate\Cache\RedisStore $instance */ /** @var \Illuminate\Cache\FileStore $instance */
return $instance->lock($name, $seconds, $owner); return $instance->lock($name, $seconds, $owner);
} }
/** /**
@ -4206,7 +4206,7 @@
*/ */
public static function restoreLock($name, $owner) public static function restoreLock($name, $owner)
{ {
/** @var \Illuminate\Cache\RedisStore $instance */ /** @var \Illuminate\Cache\FileStore $instance */
return $instance->restoreLock($name, $owner); return $instance->restoreLock($name, $owner);
} }
/** /**
@ -4217,65 +4217,30 @@
*/ */
public static function flush() public static function flush()
{ {
/** @var \Illuminate\Cache\RedisStore $instance */ /** @var \Illuminate\Cache\FileStore $instance */
return $instance->flush(); return $instance->flush();
} }
/** /**
* Get the Redis connection instance. * Get the Filesystem instance.
* *
* @return \Illuminate\Redis\Connections\Connection * @return \Illuminate\Filesystem\Filesystem
* @static * @static
*/ */
public static function connection() public static function getFilesystem()
{ {
/** @var \Illuminate\Cache\RedisStore $instance */ /** @var \Illuminate\Cache\FileStore $instance */
return $instance->connection(); return $instance->getFilesystem();
} }
/** /**
* Get the Redis connection instance that should be used to manage locks. * Get the working directory of the cache.
* *
* @return \Illuminate\Redis\Connections\Connection * @return string
* @static * @static
*/ */
public static function lockConnection() public static function getDirectory()
{ {
/** @var \Illuminate\Cache\RedisStore $instance */ /** @var \Illuminate\Cache\FileStore $instance */
return $instance->lockConnection(); return $instance->getDirectory();
}
/**
* Specify the name of the connection that should be used to store data.
*
* @param string $connection
* @return void
* @static
*/
public static function setConnection($connection)
{
/** @var \Illuminate\Cache\RedisStore $instance */
$instance->setConnection($connection);
}
/**
* Specify the name of the connection that should be used to manage locks.
*
* @param string $connection
* @return \Illuminate\Cache\RedisStore
* @static
*/
public static function setLockConnection($connection)
{
/** @var \Illuminate\Cache\RedisStore $instance */
return $instance->setLockConnection($connection);
}
/**
* Get the Redis database instance.
*
* @return \Illuminate\Contracts\Redis\Factory
* @static
*/
public static function getRedis()
{
/** @var \Illuminate\Cache\RedisStore $instance */
return $instance->getRedis();
} }
/** /**
* Get the cache key prefix. * Get the cache key prefix.
@ -4285,20 +4250,8 @@
*/ */
public static function getPrefix() public static function getPrefix()
{ {
/** @var \Illuminate\Cache\RedisStore $instance */ /** @var \Illuminate\Cache\FileStore $instance */
return $instance->getPrefix(); return $instance->getPrefix();
}
/**
* Set the cache key prefix.
*
* @param string $prefix
* @return void
* @static
*/
public static function setPrefix($prefix)
{
/** @var \Illuminate\Cache\RedisStore $instance */
$instance->setPrefix($prefix);
} }
} }
@ -9901,44 +9854,45 @@
return $instance->setConnectionName($name); return $instance->setConnectionName($name);
} }
/** /**
* Migrate the delayed jobs that are ready to the regular queue. * Release a reserved job back onto the queue after (n) seconds.
* *
* @param string $from * @param string $queue
* @param string $to * @param \Illuminate\Queue\Jobs\DatabaseJobRecord $job
* @param int $limit * @param int $delay
* @return array * @return mixed
* @static * @static
*/ */
public static function migrateExpiredJobs($from, $to) public static function release($queue, $job, $delay)
{ {
/** @var \Illuminate\Queue\RedisQueue $instance */ /** @var \Illuminate\Queue\DatabaseQueue $instance */
return $instance->migrateExpiredJobs($from, $to); return $instance->release($queue, $job, $delay);
} }
/** /**
* Delete a reserved job from the queue. * Delete a reserved job from the queue.
* *
* @param string $queue * @param string $queue
* @param \Illuminate\Queue\Jobs\RedisJob $job * @param string $id
* @return void * @return void
* @throws \Throwable
* @static * @static
*/ */
public static function deleteReserved($queue, $job) public static function deleteReserved($queue, $id)
{ {
/** @var \Illuminate\Queue\RedisQueue $instance */ /** @var \Illuminate\Queue\DatabaseQueue $instance */
$instance->deleteReserved($queue, $job); $instance->deleteReserved($queue, $id);
} }
/** /**
* Delete a reserved job from the reserved queue and release it. * Delete a reserved job from the reserved queue and release it.
* *
* @param string $queue * @param string $queue
* @param \Illuminate\Queue\Jobs\RedisJob $job * @param \Illuminate\Queue\Jobs\DatabaseJob $job
* @param int $delay * @param int $delay
* @return void * @return void
* @static * @static
*/ */
public static function deleteAndRelease($queue, $job, $delay) public static function deleteAndRelease($queue, $job, $delay)
{ {
/** @var \Illuminate\Queue\RedisQueue $instance */ /** @var \Illuminate\Queue\DatabaseQueue $instance */
$instance->deleteAndRelease($queue, $job, $delay); $instance->deleteAndRelease($queue, $job, $delay);
} }
/** /**
@ -9950,7 +9904,7 @@
*/ */
public static function clear($queue) public static function clear($queue)
{ {
/** @var \Illuminate\Queue\RedisQueue $instance */ /** @var \Illuminate\Queue\DatabaseQueue $instance */
return $instance->clear($queue); return $instance->clear($queue);
} }
/** /**
@ -9962,30 +9916,19 @@
*/ */
public static function getQueue($queue) public static function getQueue($queue)
{ {
/** @var \Illuminate\Queue\RedisQueue $instance */ /** @var \Illuminate\Queue\DatabaseQueue $instance */
return $instance->getQueue($queue); return $instance->getQueue($queue);
} }
/** /**
* Get the connection for the queue. * Get the underlying database instance.
* *
* @return \Illuminate\Redis\Connections\Connection * @return \Illuminate\Database\Connection
* @static * @static
*/ */
public static function getConnection() public static function getDatabase()
{ {
/** @var \Illuminate\Queue\RedisQueue $instance */ /** @var \Illuminate\Queue\DatabaseQueue $instance */
return $instance->getConnection(); return $instance->getDatabase();
}
/**
* Get the underlying Redis instance.
*
* @return \Illuminate\Contracts\Redis\Factory
* @static
*/
public static function getRedis()
{
/** @var \Illuminate\Queue\RedisQueue $instance */
return $instance->getRedis();
} }
/** /**
* Get the backoff for an object-based queue handler. * Get the backoff for an object-based queue handler.
@ -9996,7 +9939,7 @@
*/ */
public static function getJobBackoff($job) public static function getJobBackoff($job)
{ //Method inherited from \Illuminate\Queue\Queue { //Method inherited from \Illuminate\Queue\Queue
/** @var \Illuminate\Queue\RedisQueue $instance */ /** @var \Illuminate\Queue\DatabaseQueue $instance */
return $instance->getJobBackoff($job); return $instance->getJobBackoff($job);
} }
/** /**
@ -10008,7 +9951,7 @@
*/ */
public static function getJobExpiration($job) public static function getJobExpiration($job)
{ //Method inherited from \Illuminate\Queue\Queue { //Method inherited from \Illuminate\Queue\Queue
/** @var \Illuminate\Queue\RedisQueue $instance */ /** @var \Illuminate\Queue\DatabaseQueue $instance */
return $instance->getJobExpiration($job); return $instance->getJobExpiration($job);
} }
/** /**
@ -10020,7 +9963,7 @@
*/ */
public static function createPayloadUsing($callback) public static function createPayloadUsing($callback)
{ //Method inherited from \Illuminate\Queue\Queue { //Method inherited from \Illuminate\Queue\Queue
\Illuminate\Queue\RedisQueue::createPayloadUsing($callback); \Illuminate\Queue\DatabaseQueue::createPayloadUsing($callback);
} }
/** /**
* Get the container instance being used by the connection. * Get the container instance being used by the connection.
@ -10030,7 +9973,7 @@
*/ */
public static function getContainer() public static function getContainer()
{ //Method inherited from \Illuminate\Queue\Queue { //Method inherited from \Illuminate\Queue\Queue
/** @var \Illuminate\Queue\RedisQueue $instance */ /** @var \Illuminate\Queue\DatabaseQueue $instance */
return $instance->getContainer(); return $instance->getContainer();
} }
/** /**
@ -10042,7 +9985,7 @@
*/ */
public static function setContainer($container) public static function setContainer($container)
{ //Method inherited from \Illuminate\Queue\Queue { //Method inherited from \Illuminate\Queue\Queue
/** @var \Illuminate\Queue\RedisQueue $instance */ /** @var \Illuminate\Queue\DatabaseQueue $instance */
$instance->setContainer($container); $instance->setContainer($container);
} }
@ -17854,6 +17797,25 @@
/** /**
* *
* *
* @method static void createSubscription(array|string $channels, \Closure $callback, string $method = 'subscribe')
* @method static \Illuminate\Redis\Limiters\ConcurrencyLimiterBuilder funnel(string $name)
* @method static \Illuminate\Redis\Limiters\DurationLimiterBuilder throttle(string $name)
* @method static mixed client()
* @method static void subscribe(array|string $channels, \Closure $callback)
* @method static void psubscribe(array|string $channels, \Closure $callback)
* @method static mixed command(string $method, array $parameters = [])
* @method static void listen(\Closure $callback)
* @method static string|null getName()
* @method static \Illuminate\Redis\Connections\Connection setName(string $name)
* @method static \Illuminate\Contracts\Events\Dispatcher getEventDispatcher()
* @method static void setEventDispatcher(\Illuminate\Contracts\Events\Dispatcher $events)
* @method static void unsetEventDispatcher()
* @method static void macro(string $name, object|callable $macro)
* @method static void mixin(object $mixin, bool $replace = true)
* @method static bool hasMacro(string $name)
* @method static void flushMacros()
* @method static mixed macroCall(string $method, array $parameters)
* @see \Illuminate\Redis\RedisManager
*/ */
class Redis { class Redis {
/** /**

View File

@ -177,7 +177,7 @@ class PreviewController extends BaseController
public function design(DesignPreviewRequest $request) public function design(DesignPreviewRequest $request)
{ {
if(Ninja::isHosted() && !in_array($request->getHost(), ['preview.invoicing.co','staging.invoicing.co'])) if(Ninja::isHosted() && !in_array($request->getHost(), ['preview.invoicing.co','staging.invoicing.co'])){
return response()->json(['message' => 'This server cannot handle this request.'], 400); return response()->json(['message' => 'This server cannot handle this request.'], 400);
} }
@ -351,7 +351,7 @@ class PreviewController extends BaseController
{ {
if(Ninja::isHosted() && !in_array($request->getHost(), ['preview.invoicing.co','staging.invoicing.co'])) if(Ninja::isHosted() && !in_array($request->getHost(), ['preview.invoicing.co','staging.invoicing.co']))
return response()->json(['message' => 'This server cannot handle this request.'], 400); return response()->json(['message' => 'This server cannot handle this request.'], 400);
}
$company = auth()->user()->company(); $company = auth()->user()->company();

View File

@ -146,8 +146,8 @@ class BaseRepository
* @throws \ReflectionException * @throws \ReflectionException
*/ */
protected function alternativeSave($data, $model) protected function alternativeSave($data, $model)
{ {
if(array_key_exists('client_id', $data) && !empty($data['client_id'])) if (array_key_exists('client_id', $data) && !empty($data['client_id'])) {
$model->client_id = $data['client_id']; $model->client_id = $data['client_id'];
} }
@ -177,190 +177,191 @@ class BaseRepository
if (isset($tmp_data['client_contacts'])) { if (isset($tmp_data['client_contacts'])) {
unset($tmp_data['client_contacts']); unset($tmp_data['client_contacts']);
$model->fill($tmp_data); $model->fill($tmp_data);
$model->custom_surcharge_tax1 = $client->company->custom_surcharge_taxes1; $model->custom_surcharge_tax1 = $client->company->custom_surcharge_taxes1;
$model->custom_surcharge_tax2 = $client->company->custom_surcharge_taxes2; $model->custom_surcharge_tax2 = $client->company->custom_surcharge_taxes2;
$model->custom_surcharge_tax3 = $client->company->custom_surcharge_taxes3; $model->custom_surcharge_tax3 = $client->company->custom_surcharge_taxes3;
$model->custom_surcharge_tax4 = $client->company->custom_surcharge_taxes4; $model->custom_surcharge_tax4 = $client->company->custom_surcharge_taxes4;
if (!$model->id) { if (!$model->id) {
$this->new_model = true; $this->new_model = true;
if (is_array($model->line_items) && !($model instanceof RecurringInvoice)) { if (is_array($model->line_items) && !($model instanceof RecurringInvoice)) {
$model->line_items = (collect($model->line_items))->map(function ($item) use ($model, $client) { $model->line_items = (collect($model->line_items))->map(function ($item) use ($model, $client) {
$item->notes = Helpers::processReservedKeywords($item->notes, $client); $item->notes = Helpers::processReservedKeywords($item->notes, $client);
return $item; return $item;
}); });
}
}
$model->saveQuietly();
/* Model now persisted, now lets do some child tasks */
if ($model instanceof Invoice) {
$model->service()->setReminder()->save();
}
/* Save any documents */
if (array_key_exists('documents', $data)) {
$this->saveDocuments($data['documents'], $model);
}
if (array_key_exists('file', $data)) {
$this->saveDocuments($data['file'], $model);
}
/* If invitations are present we need to filter existing invitations with the new ones */
if (isset($data['invitations'])) {
$invitations = collect($data['invitations']);
/* Get array of Keys which have been removed from the invitations array and soft delete each invitation */
$model->invitations->pluck('key')->diff($invitations->pluck('key'))->each(function ($invitation) use ($resource) {
$invitation_class = sprintf('App\\Models\\%sInvitation', $resource);
$invitation = $invitation_class::where('key', $invitation)->first();
if ($invitation) {
$invitation->delete();
} }
}); }
foreach ($data['invitations'] as $invitation) { $model->saveQuietly();
//if no invitations are present - create one.
if (! $this->getInvitation($invitation, $resource)) { /* Model now persisted, now lets do some child tasks */
if (isset($invitation['id'])) {
unset($invitation['id']); if ($model instanceof Invoice) {
$model->service()->setReminder()->save();
}
/* Save any documents */
if (array_key_exists('documents', $data)) {
$this->saveDocuments($data['documents'], $model);
}
if (array_key_exists('file', $data)) {
$this->saveDocuments($data['file'], $model);
}
/* If invitations are present we need to filter existing invitations with the new ones */
if (isset($data['invitations'])) {
$invitations = collect($data['invitations']);
/* Get array of Keys which have been removed from the invitations array and soft delete each invitation */
$model->invitations->pluck('key')->diff($invitations->pluck('key'))->each(function ($invitation) use ($resource) {
$invitation_class = sprintf('App\\Models\\%sInvitation', $resource);
$invitation = $invitation_class::where('key', $invitation)->first();
if ($invitation) {
$invitation->delete();
} }
});
//make sure we are creating an invite for a contact who belongs to the client only! foreach ($data['invitations'] as $invitation) {
$contact = ClientContact::find($invitation['client_contact_id']); //if no invitations are present - create one.
if (! $this->getInvitation($invitation, $resource)) {
if (isset($invitation['id'])) {
unset($invitation['id']);
}
if ($contact && $model->client_id == $contact->client_id) { //make sure we are creating an invite for a contact who belongs to the client only!
$invitation_class = sprintf('App\\Models\\%sInvitation', $resource); $contact = ClientContact::find($invitation['client_contact_id']);
$new_invitation = $invitation_class::withTrashed() if ($contact && $model->client_id == $contact->client_id) {
->where('client_contact_id', $contact->id) $invitation_class = sprintf('App\\Models\\%sInvitation', $resource);
->where($lcfirst_resource_id, $model->id)
->first();
if ($new_invitation && $new_invitation->trashed()) { $new_invitation = $invitation_class::withTrashed()
$new_invitation->restore(); ->where('client_contact_id', $contact->id)
} else { ->where($lcfirst_resource_id, $model->id)
$invitation_factory_class = sprintf('App\\Factory\\%sInvitationFactory', $resource); ->first();
$new_invitation = $invitation_factory_class::create($model->company_id, $model->user_id);
$new_invitation->{$lcfirst_resource_id} = $model->id; if ($new_invitation && $new_invitation->trashed()) {
$new_invitation->client_contact_id = $contact->id; $new_invitation->restore();
$new_invitation->key = $this->createDbHash($model->company->db); } else {
$new_invitation->saveQuietly(); $invitation_factory_class = sprintf('App\\Factory\\%sInvitationFactory', $resource);
$new_invitation = $invitation_factory_class::create($model->company_id, $model->user_id);
$new_invitation->{$lcfirst_resource_id} = $model->id;
$new_invitation->client_contact_id = $contact->id;
$new_invitation->key = $this->createDbHash($model->company->db);
$new_invitation->saveQuietly();
}
} }
} }
} }
} }
/* If no invitations have been created, this is our fail safe to maintain state*/
if ($model->invitations()->count() == 0) {
$model->service()->createInvitations();
}
/* Recalculate invoice amounts */
$model = $model->calc()->getInvoice();
/* We use this to compare to our starting amount */
$state['finished_amount'] = $model->amount;
/* Apply entity number */
$model = $model->service()->applyNumber()->save();
/* Handle attempts where the deposit is greater than the amount/balance of the invoice */
if ((int)$model->balance != 0 && $model->partial > $model->amount && $model->amount > 0) {
$model->partial = min($model->amount, $model->balance);
}
/* Update product details if necessary - if we are inside a transaction - do nothing */
if ($model->company->update_products && $model->id && \DB::transactionLevel() == 0) {
UpdateOrCreateProduct::dispatch($model->line_items, $model, $model->company);
}
/* Perform model specific tasks */
if ($model instanceof Invoice) {
if (($state['finished_amount'] != $state['starting_amount']) && ($model->status_id != Invoice::STATUS_DRAFT)) {
$model->service()->updateStatus()->save();
$model->client->service()->updateBalance(($state['finished_amount'] - $state['starting_amount']))->save();
$model->ledger()->updateInvoiceBalance(($state['finished_amount'] - $state['starting_amount']), "Update adjustment for invoice {$model->number}");
}
if (! $model->design_id) {
$model->design_id = $this->decodePrimaryKey($client->getSetting('invoice_design_id'));
}
//links tasks and expenses back to the invoice, but only if we are not in the middle of a transaction.
if (\DB::transactionLevel() == 0) {
$model->service()->linkEntities()->save();
}
if ($this->new_model) {
event('eloquent.created: App\Models\Invoice', $model);
} else {
event('eloquent.updated: App\Models\Invoice', $model);
}
}
if ($model instanceof Credit) {
$model = $model->calc()->getCredit();
if (! $model->design_id) {
$model->design_id = $this->decodePrimaryKey($client->getSetting('credit_design_id'));
}
if (array_key_exists('invoice_id', $data) && $data['invoice_id']) {
$model->invoice_id = $data['invoice_id'];
}
if ($this->new_model) {
event('eloquent.created: App\Models\Credit', $model);
} else {
event('eloquent.updated: App\Models\Credit', $model);
}
if (($state['finished_amount'] != $state['starting_amount']) && ($model->status_id != Credit::STATUS_DRAFT)) {
$model->client->service()->adjustCreditBalance(($state['finished_amount'] - $state['starting_amount']))->save();
}
}
if ($model instanceof Quote) {
if (! $model->design_id) {
$model->design_id = $this->decodePrimaryKey($client->getSetting('quote_design_id'));
}
$model = $model->calc()->getQuote();
if ($this->new_model) {
event('eloquent.created: App\Models\Quote', $model);
} else {
event('eloquent.updated: App\Models\Quote', $model);
}
}
if ($model instanceof RecurringInvoice) {
if (! $model->design_id) {
$model->design_id = $this->decodePrimaryKey($client->getSetting('invoice_design_id'));
}
$model = $model->calc()->getRecurringInvoice();
if ($this->new_model) {
event('eloquent.created: App\Models\RecurringInvoice', $model);
} else {
event('eloquent.updated: App\Models\RecurringInvoice', $model);
}
}
$model->saveQuietly();
return $model->fresh();
} }
/* If no invitations have been created, this is our fail safe to maintain state*/
if ($model->invitations()->count() == 0) {
$model->service()->createInvitations();
}
/* Recalculate invoice amounts */
$model = $model->calc()->getInvoice();
/* We use this to compare to our starting amount */
$state['finished_amount'] = $model->amount;
/* Apply entity number */
$model = $model->service()->applyNumber()->save();
/* Handle attempts where the deposit is greater than the amount/balance of the invoice */
if ((int)$model->balance != 0 && $model->partial > $model->amount && $model->amount > 0) {
$model->partial = min($model->amount, $model->balance);
}
/* Update product details if necessary - if we are inside a transaction - do nothing */
if ($model->company->update_products && $model->id && \DB::transactionLevel() == 0) {
UpdateOrCreateProduct::dispatch($model->line_items, $model, $model->company);
}
/* Perform model specific tasks */
if ($model instanceof Invoice) {
if (($state['finished_amount'] != $state['starting_amount']) && ($model->status_id != Invoice::STATUS_DRAFT)) {
$model->service()->updateStatus()->save();
$model->client->service()->updateBalance(($state['finished_amount'] - $state['starting_amount']))->save();
$model->ledger()->updateInvoiceBalance(($state['finished_amount'] - $state['starting_amount']), "Update adjustment for invoice {$model->number}");
}
if (! $model->design_id) {
$model->design_id = $this->decodePrimaryKey($client->getSetting('invoice_design_id'));
}
//links tasks and expenses back to the invoice, but only if we are not in the middle of a transaction.
if (\DB::transactionLevel() == 0) {
$model->service()->linkEntities()->save();
}
if ($this->new_model) {
event('eloquent.created: App\Models\Invoice', $model);
} else {
event('eloquent.updated: App\Models\Invoice', $model);
}
}
if ($model instanceof Credit) {
$model = $model->calc()->getCredit();
if (! $model->design_id) {
$model->design_id = $this->decodePrimaryKey($client->getSetting('credit_design_id'));
}
if (array_key_exists('invoice_id', $data) && $data['invoice_id']) {
$model->invoice_id = $data['invoice_id'];
}
if ($this->new_model) {
event('eloquent.created: App\Models\Credit', $model);
} else {
event('eloquent.updated: App\Models\Credit', $model);
}
if (($state['finished_amount'] != $state['starting_amount']) && ($model->status_id != Credit::STATUS_DRAFT)) {
$model->client->service()->adjustCreditBalance(($state['finished_amount'] - $state['starting_amount']))->save();
}
}
if ($model instanceof Quote) {
if (! $model->design_id) {
$model->design_id = $this->decodePrimaryKey($client->getSetting('quote_design_id'));
}
$model = $model->calc()->getQuote();
if ($this->new_model) {
event('eloquent.created: App\Models\Quote', $model);
} else {
event('eloquent.updated: App\Models\Quote', $model);
}
}
if ($model instanceof RecurringInvoice) {
if (! $model->design_id) {
$model->design_id = $this->decodePrimaryKey($client->getSetting('invoice_design_id'));
}
$model = $model->calc()->getRecurringInvoice();
if ($this->new_model) {
event('eloquent.created: App\Models\RecurringInvoice', $model);
} else {
event('eloquent.updated: App\Models\RecurringInvoice', $model);
}
}
$model->saveQuietly();
return $model->fresh();
} }
} }