akaunting 3.0 (the last dance)

This commit is contained in:
Burak Civan
2022-06-01 10:15:55 +03:00
parent cead09f6d4
commit d9c0764572
3812 changed files with 126831 additions and 102949 deletions

View File

@ -3,34 +3,54 @@
namespace App\Traits;
use App\Models\Document\Document;
use App\Abstracts\View\Components\Document as DocumentComponent;
use App\Abstracts\View\Components\Documents\Document as DocumentComponent;
use App\Utilities\Date;
use App\Traits\Transactions;
use Egulias\EmailValidator\EmailValidator;
use Egulias\EmailValidator\Validation\DNSCheckValidation;
use Egulias\EmailValidator\Validation\MultipleValidationWithAnd;
use Egulias\EmailValidator\Validation\RFCValidation;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
trait Documents
{
use Transactions;
public function isRecurringDocument(): bool
{
$type = $this->type ?? $this->document->type ?? $this->model->type ?? 'invoice';
return Str::endsWith($type, '-recurring');
}
public function isNotRecurringDocument(): bool
{
return ! $this->isRecurring();
}
public function getNextDocumentNumber(string $type): string
{
if ($alias = config('type.' . $type . '.alias')) {
if ($alias = config('type.document.' . $type . '.alias')) {
$type = $alias . '.' . str_replace('-', '_', $type);
}
$prefix = setting("$type.number_prefix");
$next = setting("$type.number_next");
$digit = setting("$type.number_digit");
$prefix = setting($type . '.number_prefix');
$next = setting($type . '.number_next');
$digit = setting($type . '.number_digit');
return $prefix . str_pad($next, $digit, '0', STR_PAD_LEFT);
}
public function increaseNextDocumentNumber(string $type): void
{
if ($alias = config('type.' . $type . '.alias')) {
if ($alias = config('type.document.' . $type . '.alias')) {
$type = $alias . '.' . str_replace('-', '_', $type);
}
$next = setting("$type.number_next", 1) + 1;
$next = setting($type . '.number_next', 1) + 1;
setting(["$type.number_next" => $next]);
setting([$type . '.number_next' => $next]);
setting()->save();
}
@ -74,6 +94,17 @@ trait Documents
return $statuses;
}
public function getDocumentStatusesForFuture()
{
return [
'draft',
'sent',
'received',
'viewed',
'partial',
];
}
public function getDocumentFileName(Document $document, string $separator = '-', string $extension = 'pdf'): string
{
return $this->getSafeDocumentNumber($document, $separator) . $separator . time() . '.' . $extension;
@ -86,7 +117,7 @@ trait Documents
protected function getTextDocumentStatuses($type)
{
$default_key = config('type.' . $type . '.translation.prefix') . '.statuses.';
$default_key = config('type.document.' . $type . '.translation.prefix') . '.statuses.';
$translation = DocumentComponent::getTextFromConfig($type, 'document_status', $default_key);
@ -94,10 +125,10 @@ trait Documents
return $translation;
}
$alias = config('type.' . $type . '.alias');
$alias = config('type.document.' . $type . '.alias');
if (!empty($alias)) {
$translation = $alias . '::' . config('type.' . $type . '.translation.prefix') . '.statuses';
$translation = $alias . '::' . config('type.document.' . $type . '.translation.prefix') . '.statuses';
if (is_array(trans($translation))) {
return $translation . '.';
@ -110,13 +141,13 @@ trait Documents
protected function getSettingKey($type, $setting_key)
{
$key = '';
$alias = config('type.' . $type . '.alias');
$alias = config('type.document.' . $type . '.alias');
if (!empty($alias)) {
if (! empty($alias)) {
$key .= $alias . '.';
}
$prefix = config('type.' . $type . '.setting.prefix');
$prefix = config('type.document.' . $type . '.setting.prefix');
$key .= $prefix . '.' . $setting_key;
@ -143,4 +174,80 @@ trait Documents
return $pdf_path;
}
public function getTotalsForFutureDocuments($type = 'invoice', $documents = null)
{
$totals = [
'overdue' => 0,
'open' => 0,
'draft' => 0,
];
$today = Date::today()->toDateString();
$documents = $documents ?: Document::type($type)->with('transactions')->future();
$documents->each(function ($document) use (&$totals, $today) {
if (!in_array($document->status, $this->getDocumentStatusesForFuture())) {
return;
}
$payments = 0;
if ($document->status == 'draft') {
$totals['draft'] += $document->getAmountConvertedToDefault();
return;
}
if ($document->status == 'partial') {
foreach ($document->transactions as $transaction) {
$payments += $transaction->getAmountConvertedToDefault();
}
}
// Check if the document is open or overdue
if ($document->due_at > $today) {
$totals['open'] += $document->getAmountConvertedToDefault() - $payments;
} else {
$totals['overdue'] += $document->getAmountConvertedToDefault() - $payments;
}
});
return $totals;
}
public function canNotifyTheContactOfDocument(Document $document): bool
{
$config = config('type.document.' . $document->type . '.notification');
if (! $config['notify_contact']) {
return false;
}
if (! $document->contact || ($document->contact->enabled == 0)) {
return false;
}
if (empty($document->contact_email)) {
return false;
}
// Check if ietf.org has MX records signaling a server with email capabilites
$validator = new EmailValidator();
$validations = new MultipleValidationWithAnd([
new RFCValidation(),
new DNSCheckValidation(),
]);
if (! $validator->isValid($document->contact_email, $validations)) {
return false;
}
return true;
}
public function getRealTypeOfRecurringDocument(string $recurring_type): string
{
return Str::replace('-recurring', '', $recurring_type);
}
}