akaunting/app/Traits/Recurring.php

234 lines
7.5 KiB
PHP
Raw Normal View History

2018-04-27 16:01:31 +03:00
<?php
namespace App\Traits;
2022-06-01 10:15:55 +03:00
use App\Models\Common\Recurring as Model;
2020-09-30 17:01:35 +03:00
use App\Utilities\Date;
2018-05-02 00:59:55 +03:00
use Recurr\Rule;
use Recurr\Transformer\ArrayTransformer;
use Recurr\Transformer\ArrayTransformerConfig;
2018-04-27 16:01:31 +03:00
trait Recurring
{
2021-04-01 11:17:02 +03:00
public function createRecurring($request)
2018-04-27 16:01:31 +03:00
{
2021-04-01 11:17:02 +03:00
if (empty($request['recurring_frequency']) || ($request['recurring_frequency'] == 'no')) {
2018-04-27 16:01:31 +03:00
return;
}
$frequency = ($request['recurring_frequency'] != 'custom') ? $request['recurring_frequency'] : $request['recurring_custom_frequency'];
2020-03-04 13:40:25 +03:00
$interval = (($request['recurring_frequency'] != 'custom') || ($request['recurring_interval'] < 1)) ? 1 : (int) $request['recurring_interval'];
2022-06-01 10:15:55 +03:00
$started_at = !empty($request['recurring_started_at']) ? $request['recurring_started_at'] : Date::now();
$status = !empty($request['recurring_status']) ? $request['recurring_status'] : Model::ACTIVE_STATUS;
$limit_by = !empty($request['recurring_limit']) ? $request['recurring_limit'] : 'count';
$limit_count = isset($request['recurring_limit_count']) ? (int) $request['recurring_limit_count'] : 0;
$limit_date = !empty($request['recurring_limit_date']) ? $request['recurring_limit_date'] : null;
$auto_send = !empty($request['recurring_send_email']) ? $request['recurring_send_email'] : 0;
2021-09-07 10:33:34 +03:00
$source = !empty($request['created_from']) ? $request['created_from'] : source_name();
$owner = !empty($request['created_by']) ? $request['created_by'] : user_id();
2018-04-27 16:01:31 +03:00
$this->recurring()->create([
2022-06-01 10:15:55 +03:00
'company_id' => $this->company_id,
'frequency' => $frequency,
'interval' => $interval,
'started_at' => $started_at,
'status' => $status,
'limit_by' => $limit_by,
'limit_count' => $limit_count,
'limit_date' => $limit_date,
'auto_send' => $auto_send,
2022-06-01 10:15:55 +03:00
'created_from' => $source,
'created_by' => $owner,
2018-04-27 16:01:31 +03:00
]);
}
2021-04-01 11:17:02 +03:00
public function updateRecurring($request)
2018-04-27 16:01:31 +03:00
{
2021-04-01 11:17:02 +03:00
if (empty($request['recurring_frequency']) || ($request['recurring_frequency'] == 'no')) {
2018-04-27 16:01:31 +03:00
$this->recurring()->delete();
2022-06-01 10:15:55 +03:00
2018-04-27 16:01:31 +03:00
return;
}
$frequency = ($request['recurring_frequency'] != 'custom') ? $request['recurring_frequency'] : $request['recurring_custom_frequency'];
2020-03-04 13:40:25 +03:00
$interval = (($request['recurring_frequency'] != 'custom') || ($request['recurring_interval'] < 1)) ? 1 : (int) $request['recurring_interval'];
2022-06-01 10:15:55 +03:00
$started_at = !empty($request['recurring_started_at']) ? $request['recurring_started_at'] : Date::now();
$limit_by = !empty($request['recurring_limit']) ? $request['recurring_limit'] : 'count';
$limit_count = isset($request['recurring_limit_count']) ? (int) $request['recurring_limit_count'] : 0;
$limit_date = !empty($request['recurring_limit_date']) ? $request['recurring_limit_date'] : null;
$auto_send = !empty($request['recurring_send_email']) ? $request['recurring_send_email'] : 0;
2018-04-27 16:01:31 +03:00
2018-04-27 16:48:59 +03:00
$recurring = $this->recurring();
2021-09-07 10:33:34 +03:00
$model_exists = $recurring->count();
2018-04-27 16:48:59 +03:00
2021-09-07 10:33:34 +03:00
$data = [
2022-06-01 10:15:55 +03:00
'company_id' => $this->company_id,
'frequency' => $frequency,
'interval' => $interval,
'started_at' => $started_at,
'limit_by' => $limit_by,
'limit_count' => $limit_count,
'limit_date' => $limit_date,
'auto_send' => $auto_send,
2021-09-07 10:33:34 +03:00
];
2022-06-01 10:15:55 +03:00
if (! empty($request['recurring_status'])) {
$data['status'] = $request['recurring_status'];
}
2021-09-07 10:33:34 +03:00
if ($model_exists) {
$recurring->update($data);
} else {
$source = !empty($request['created_from']) ? $request['created_from'] : source_name();
$owner = !empty($request['created_by']) ? $request['created_by'] : user_id();
$recurring->create(array_merge($data, [
2022-06-01 10:15:55 +03:00
'status' => Model::ACTIVE_STATUS,
'created_from' => $source,
'created_by' => $owner,
2021-09-07 10:33:34 +03:00
]));
}
2018-04-27 16:01:31 +03:00
}
2018-05-02 00:59:55 +03:00
2022-06-01 10:15:55 +03:00
public function getRecurringSchedule()
2018-05-02 00:59:55 +03:00
{
2020-09-27 00:33:06 +03:00
$config = new ArrayTransformerConfig();
$config->enableLastDayOfMonthFix();
2020-09-30 17:01:35 +03:00
$config->setVirtualLimit($this->getRecurringVirtualLimit());
2018-05-02 00:59:55 +03:00
2020-09-27 00:33:06 +03:00
$transformer = new ArrayTransformer();
$transformer->setConfig($config);
2022-06-01 10:15:55 +03:00
return $transformer->transform($this->getRecurringRule());
2018-05-02 00:59:55 +03:00
}
2022-06-01 10:15:55 +03:00
public function getRecurringRule()
2018-05-02 00:59:55 +03:00
{
2020-09-27 00:33:06 +03:00
$rule = (new Rule())
->setStartDate($this->getRecurringRuleStartDate())
->setTimezone($this->getRecurringRuleTimeZone())
->setFreq($this->getRecurringRuleFrequency())
->setInterval($this->getRecurringRuleInterval());
2018-05-02 00:59:55 +03:00
2022-06-01 10:15:55 +03:00
if ($this->limit_by == 'date') {
2021-10-09 18:34:37 +03:00
$rule->setUntil($this->getRecurringRuleUntilDate());
2022-06-01 10:15:55 +03:00
} elseif ($this->limit_count != 0) {
// 0 means infinite
$rule->setCount($this->getRecurringRuleCount());
2021-10-09 18:34:37 +03:00
}
2020-09-27 00:33:06 +03:00
return $rule;
2018-05-02 00:59:55 +03:00
}
2020-09-27 00:33:06 +03:00
public function getRecurringRuleStartDate()
2018-05-02 00:59:55 +03:00
{
2022-06-01 10:15:55 +03:00
return $this->getRecurringRuleDate($this->started_at);
2020-09-27 00:33:06 +03:00
}
2018-05-02 00:59:55 +03:00
2020-09-30 17:01:35 +03:00
public function getRecurringRuleUntilDate()
{
2022-06-01 10:15:55 +03:00
return $this->getRecurringRuleDate($this->limit_date);
}
public function getRecurringRuleTodayDate()
{
return $this->getRecurringRuleDate(Date::today()->toDateTimeString());
}
public function getRecurringRuleTomorrowDate()
{
return $this->getRecurringRuleDate(Date::tomorrow()->toDateTimeString());
}
public function getRecurringRuleDate($date)
{
return new \DateTime($date, new \DateTimeZone($this->getRecurringRuleTimeZone()));
2020-09-30 17:01:35 +03:00
}
2020-09-27 00:33:06 +03:00
public function getRecurringRuleTimeZone()
{
return setting('localisation.timezone');
2018-05-02 00:59:55 +03:00
}
2020-09-27 00:33:06 +03:00
public function getRecurringRuleCount()
2018-05-02 00:59:55 +03:00
{
2022-06-07 17:52:54 +03:00
return $this->limit_count;
2020-09-27 00:33:06 +03:00
}
2018-05-02 00:59:55 +03:00
2020-09-27 00:33:06 +03:00
public function getRecurringRuleFrequency()
{
return strtoupper($this->frequency);
2018-05-02 00:59:55 +03:00
}
2020-09-27 00:33:06 +03:00
public function getRecurringRuleInterval()
2018-05-02 00:59:55 +03:00
{
2020-09-27 00:33:06 +03:00
return $this->interval;
}
2018-05-02 00:59:55 +03:00
2020-09-30 17:01:35 +03:00
public function getRecurringVirtualLimit()
{
switch ($this->frequency) {
case 'yearly':
$limit = '2';
break;
case 'monthly':
$limit = '24';
break;
case 'weekly':
$limit = '104';
break;
case 'daily':
default;
$limit = '732';
break;
}
return $limit;
}
2023-05-09 10:53:13 +03:00
public function getNextRecurring()
2020-09-27 00:33:06 +03:00
{
2022-06-01 10:15:55 +03:00
if (! $schedule = $this->getRecurringSchedule()) {
2020-09-27 00:33:06 +03:00
return false;
}
2018-05-02 00:59:55 +03:00
2023-05-09 10:53:13 +03:00
$schedule = $schedule->startsAfter($this->getRecurringRuleTodayDate());
2018-05-02 00:59:55 +03:00
2023-05-09 10:53:13 +03:00
if ($schedule->count() == 0) {
2020-09-27 00:33:06 +03:00
return false;
}
2018-05-02 00:59:55 +03:00
2023-05-09 10:53:13 +03:00
if (! $next = $schedule->current()) {
2020-09-27 00:33:06 +03:00
return false;
2018-05-02 00:59:55 +03:00
}
2020-09-27 00:33:06 +03:00
return $next->getStart();
2018-05-02 00:59:55 +03:00
}
2020-09-27 00:33:06 +03:00
public function getFirstRecurring()
2018-05-02 00:59:55 +03:00
{
2022-06-01 10:15:55 +03:00
if (! $schedule = $this->getRecurringSchedule()) {
2020-09-27 00:33:06 +03:00
return false;
}
2018-05-02 00:59:55 +03:00
2022-11-14 00:20:04 +03:00
if (! $first = $schedule->first()) {
return false;
}
return $first->getStart();
2018-05-02 00:59:55 +03:00
}
2020-09-27 00:33:06 +03:00
public function getLastRecurring()
2018-05-02 00:59:55 +03:00
{
2022-06-01 10:15:55 +03:00
if (! $schedule = $this->getRecurringSchedule()) {
2020-09-27 00:33:06 +03:00
return false;
}
2018-05-02 00:59:55 +03:00
2022-11-14 00:20:04 +03:00
if (! $last = $schedule->last()) {
return false;
}
return $last->getStart();
2018-05-02 00:59:55 +03:00
}
2019-11-16 10:21:14 +03:00
}