Merge branch 'master' of github.com:akaunting/akaunting

This commit is contained in:
Cüneyt Şentürk 2023-05-31 14:40:15 +03:00
commit 203eeb1885
10 changed files with 139 additions and 23 deletions

View File

@ -34,6 +34,22 @@ class Uploads extends Controller
return $this->streamMedia($media); return $this->streamMedia($media);
} }
public function inline($id)
{
try {
$media = Media::find($id);
} catch (\Exception $e) {
return response(null, 204);
}
// Get file path
if (!$this->getMediaPathOnStorage($media)) {
return response(null, 204);
}
return $this->streamMedia($media, 'inline');
}
/** /**
* Get the specified resource. * Get the specified resource.
* *

View File

@ -14,9 +14,10 @@ class CustomMail extends FormRequest
public function rules() public function rules()
{ {
return [ return [
'to' => 'required|email', 'to' => 'required|email',
'subject' => 'required|string', 'subject' => 'required|string',
'body' => 'required|string', 'body' => 'required|string',
'attachments.*' => 'nullable|boolean',
]; ];
} }
} }

View File

@ -30,10 +30,15 @@ class SendDocumentAsCustomMail extends Job
$custom_mail['cc'] = user()->email; $custom_mail['cc'] = user()->email;
} }
$attachments = collect($this->request->get('attachments', []))
->filter(fn($value) => $value == true)
->keys()
->all();
$notification = config('type.document.' . $document->type . '.notification.class'); $notification = config('type.document.' . $document->type . '.notification.class');
// Notify the contact // Notify the contact
$document->contact->notify(new $notification($document, $this->template_alias, true, $custom_mail)); $document->contact->notify(new $notification($document, $this->template_alias, true, $custom_mail, $attachments));
event(new DocumentSent($document)); event(new DocumentSent($document));
} }

View File

@ -35,10 +35,17 @@ class Invoice extends Notification
*/ */
public $attach_pdf; public $attach_pdf;
/**
* List of document attachments to attach when sending the email.
*
* @var array
*/
public $attachments;
/** /**
* Create a notification instance. * Create a notification instance.
*/ */
public function __construct(Document $invoice = null, string $template_alias = null, bool $attach_pdf = false, array $custom_mail = []) public function __construct(Document $invoice = null, string $template_alias = null, bool $attach_pdf = false, array $custom_mail = [], $attachments = [])
{ {
parent::__construct(); parent::__construct();
@ -46,6 +53,7 @@ class Invoice extends Notification
$this->template = EmailTemplate::alias($template_alias)->first(); $this->template = EmailTemplate::alias($template_alias)->first();
$this->attach_pdf = $attach_pdf; $this->attach_pdf = $attach_pdf;
$this->custom_mail = $custom_mail; $this->custom_mail = $custom_mail;
$this->attachments = $attachments;
} }
/** /**
@ -68,6 +76,17 @@ class Invoice extends Notification
]); ]);
} }
// Attach selected attachments
if (! empty($this->invoice->attachment)) {
foreach ($this->invoice->attachment as $attachment) {
if (in_array($attachment->id, $this->attachments)) {
$message->attach($attachment->getAbsolutePath(), [
'mime' => $attachment->mime_type,
]);
}
}
}
return $message; return $message;
} }

View File

@ -118,7 +118,7 @@ trait Uploads
return $path; return $path;
} }
public function streamMedia($media) public function streamMedia($media, $disposition = 'attachment')
{ {
return response()->streamDownload( return response()->streamDownload(
function() use ($media) { function() use ($media) {
@ -133,6 +133,7 @@ trait Uploads
'Content-Type' => $media->mime_type, 'Content-Type' => $media->mime_type,
'Content-Length' => $media->size, 'Content-Length' => $media->size,
], ],
$disposition,
); );
} }

View File

@ -20,11 +20,7 @@ class NumberDigit extends Form
if (empty($this->name)) { if (empty($this->name)) {
$this->name = 'number_digit'; $this->name = 'number_digit';
} }
if (empty($this->label)) {
$this->label = trans('settings.invoice.digit');
}
$this->number_digits = [ $this->number_digits = [
'1' => '1', '1' => '1',
'2' => '2', '2' => '2',

View File

@ -230,6 +230,7 @@ return [
'go_back' => 'Go back to :type', 'go_back' => 'Go back to :type',
'validation_error' => 'Validation error', 'validation_error' => 'Validation error',
'dismiss' => 'Dismiss', 'dismiss' => 'Dismiss',
'size' => 'Size',
'card' => [ 'card' => [
'cards' => 'Card|Cards', 'cards' => 'Card|Cards',

View File

@ -1,15 +1,91 @@
<x-form id="form-email" :route="[$store_route, $invoice->id]"> <x-form id="form-email" :route="[$store_route, $invoice->id]">
<x-form.section> <x-tabs active="general" class="grid grid-cols-{{ $invoice->attachment ? '2' : '1' }}" override="class" ignore-hash>
<x-slot name="body"> <x-slot name="navs">
<x-form.group.text name="to" label="{{ trans('general.to') }}" value="{{ $invoice->contact->email }}" form-group-class="sm:col-span-6" /> <x-tabs.nav id="general">
{{ trans('general.general') }}
</x-tabs.nav>
<x-form.group.text name="subject" label="{{ trans('settings.email.templates.subject') }}" value="{{ $notification->getSubject() }}" form-group-class="sm:col-span-6" /> @if ($invoice->attachment)
<x-tabs.nav id="attachments">
<x-form.group.editor name="body" label="{{ trans('settings.email.templates.body') }}" :value="$notification->getBody()" rows="5" data-toggle="quill" form-group-class="sm:col-span-6 mb-0" /> {{ trans_choice('general.attachments', 2) }}
</x-tabs.nav>
<x-form.group.checkbox name="user_email" :options="['1' => trans('general.email_send_me', ['email' => user()->email])]" checkbox-class="col-span-6" /> @endif
<x-form.input.hidden name="document_id" :value="$invoice->id" />
</x-slot> </x-slot>
</x-form.section>
<x-slot name="content">
<x-tabs.tab id="general">
<x-form.section>
<x-slot name="body">
<x-form.group.text name="to" label="{{ trans('general.to') }}" value="{{ $invoice->contact->email }}" form-group-class="sm:col-span-6" />
<x-form.group.text name="subject" label="{{ trans('settings.email.templates.subject') }}" value="{{ $notification->getSubject() }}" form-group-class="sm:col-span-6" />
<x-form.group.editor name="body" label="{{ trans('settings.email.templates.body') }}" :value="$notification->getBody()" rows="5" data-toggle="quill" form-group-class="sm:col-span-6 mb-0" />
<x-form.group.checkbox name="user_email" :options="['1' => trans('general.email_send_me', ['email' => user()->email])]" checkbox-class="col-span-6" />
<x-form.input.hidden name="document_id" :value="$invoice->id" />
</x-slot>
</x-form.section>
</x-tabs.tab>
@if ($invoice->attachment)
<x-tabs.tab id="attachments">
<x-table>
<x-table.thead>
<x-table.tr class="flex items-center px-1">
<x-table.th class="w-1/12">
</x-table.th>
<x-table.th class="w-1/6">
</x-table.th>
<x-table.th class="w-4/6">
{{ trans('general.name') }}
</x-table.th>
<x-table.th class="w-1/6">
{{ trans('general.size') }}
</x-table.th>
</x-table.tr>
</x-table.thead>
<x-table.tbody>
@foreach($invoice->attachment as $attachment)
<x-table.tr id="method-{{ $attachment->id }}">
<x-table.td class="w-1/12">
<input type="checkbox"
id="attachment-{{ $attachment->id }}"
name="{{ $attachment->id }}"
class="rounded-sm text-purple border-gray-300 cursor-pointer disabled:bg-gray-200 focus:outline-none focus:ring-transparent"
data-field="attachments"
@input="e => form.attachments[e.target.name] = e.target.checked | 0">
</x-table.td>
<x-table.td class="w-1/6">
@if ($attachment->aggregate_type == 'image')
<div class="avatar-attachment">
<img src="{{ route('uploads.get', $attachment->id) }}" alt="{{ $attachment->basename }}" class="avatar-img h-full rounded object-cover">
</div>
@else
<div class="avatar-attachment">
<span class="material-icons text-base">attach_file</span>
</div>
@endif
</x-table.td>
<x-table.td class="w-4/6">
{{ $attachment->basename }}
</x-table.td>
<x-table.td class="w-1/6">
{{ $attachment->readableSize() }}
</x-table.td>
</x-table.tr>
@endforeach
</x-table.tbody>
</x-table>
</x-tabs.tab>
@endif
</x-slot>
</x-tabs>
</x-form> </x-form>

View File

@ -14,7 +14,7 @@
<x-slot name="body"> <x-slot name="body">
<x-form.group.text name="number_prefix" label="{{ trans('settings.invoice.prefix') }}" value="{{ setting('invoice.number_prefix') }}" not-required /> <x-form.group.text name="number_prefix" label="{{ trans('settings.invoice.prefix') }}" value="{{ setting('invoice.number_prefix') }}" not-required />
<x-form.group.number_digit :clearable="'false'" not-required /> <x-form.group.number_digit label="{{ trans('settings.invoice.digit') }}" :clearable="'false'" not-required />
<x-form.group.number name="number_next" label="{{ trans('settings.invoice.next') }}" value="{{ setting('invoice.number_next') }}" not-required /> <x-form.group.number name="number_next" label="{{ trans('settings.invoice.next') }}" value="{{ setting('invoice.number_next') }}" not-required />

View File

@ -10,6 +10,7 @@ use Illuminate\Support\Facades\Route;
*/ */
Route::group(['as' => 'uploads.', 'prefix' => 'uploads'], function () { Route::group(['as' => 'uploads.', 'prefix' => 'uploads'], function () {
Route::get('{id}/inline', 'Common\Uploads@inline')->name('inline');
Route::delete('{id}', 'Common\Uploads@destroy')->name('destroy'); Route::delete('{id}', 'Common\Uploads@destroy')->name('destroy');
}); });