diff --git a/app/Http/Controllers/BillController.php b/app/Http/Controllers/BillController.php index 548f127766..9a61d149f7 100644 --- a/app/Http/Controllers/BillController.php +++ b/app/Http/Controllers/BillController.php @@ -23,9 +23,11 @@ declare(strict_types=1); namespace FireflyIII\Http\Controllers; use Carbon\Carbon; +use FireflyIII\Helpers\Attachments\AttachmentHelperInterface; use FireflyIII\Helpers\Collector\JournalCollectorInterface; use FireflyIII\Http\Requests\BillFormRequest; use FireflyIII\Models\Bill; +use FireflyIII\Models\Note; use FireflyIII\Models\TransactionJournal; use FireflyIII\Repositories\Bill\BillRepositoryInterface; use Illuminate\Http\Request; @@ -39,6 +41,9 @@ use View; */ class BillController extends Controller { + /** @var AttachmentHelperInterface Helper for attachments. */ + private $attachments; + /** * */ @@ -46,10 +51,16 @@ class BillController extends Controller { parent::__construct(); + $maxFileSize = app('steam')->phpBytes(ini_get('upload_max_filesize')); + $maxPostSize = app('steam')->phpBytes(ini_get('post_max_size')); + $uploadSize = min($maxFileSize, $maxPostSize); + View::share('uploadSize', $uploadSize); + $this->middleware( function ($request, $next) { View::share('title', trans('firefly.bills')); View::share('mainTitleIcon', 'fa-calendar-o'); + $this->attachments = app(AttachmentHelperInterface::class); return $next($request); } @@ -138,6 +149,18 @@ class BillController extends Controller $bill->amount_min = round($bill->amount_min, $currency->decimal_places); $bill->amount_max = round($bill->amount_max, $currency->decimal_places); + $preFilled = [ + 'notes' => '', + ]; + + /** @var Note $note */ + $note = $bill->notes()->first(); + if (null !== $note) { + $preFilled['notes'] = $note->text; + } + + $request->session()->flash('preFilled', $preFilled); + $request->session()->forget('bills.edit.fromUpdate'); $request->session()->flash('gaEventCategory', 'bills'); $request->session()->flash('gaEventAction', 'edit'); @@ -246,6 +269,16 @@ class BillController extends Controller $request->session()->flash('success', strval(trans('firefly.stored_new_bill', ['name' => $bill->name]))); Preferences::mark(); + + /** @var array $files */ + $files = $request->hasFile('attachments') ? $request->file('attachments') : null; + $this->attachments->saveAttachmentsForModel($bill, $files); + + // flash messages + if (count($this->attachments->getMessages()->get('attachments')) > 0) { + $request->session()->flash('info', $this->attachments->getMessages()->get('attachments')); + } + if (1 === intval($request->get('create_another'))) { // @codeCoverageIgnoreStart $request->session()->put('bills.create.fromStore', true); @@ -273,6 +306,15 @@ class BillController extends Controller $request->session()->flash('success', strval(trans('firefly.updated_bill', ['name' => $bill->name]))); Preferences::mark(); + /** @var array $files */ + $files = $request->hasFile('attachments') ? $request->file('attachments') : null; + $this->attachments->saveAttachmentsForModel($bill, $files); + + // flash messages + if (count($this->attachments->getMessages()->get('attachments')) > 0) { + $request->session()->flash('info', $this->attachments->getMessages()->get('attachments')); + } + if (1 === intval($request->get('return_to_edit'))) { // @codeCoverageIgnoreStart $request->session()->put('bills.edit.fromUpdate', true); diff --git a/app/Http/Controllers/Transaction/SingleController.php b/app/Http/Controllers/Transaction/SingleController.php index 2fcf6e56d1..8e746e85e3 100644 --- a/app/Http/Controllers/Transaction/SingleController.php +++ b/app/Http/Controllers/Transaction/SingleController.php @@ -44,7 +44,6 @@ use Illuminate\Http\Request; use Log; use Preferences; use Session; -use Steam; use View; /** @@ -75,8 +74,8 @@ class SingleController extends Controller { parent::__construct(); - $maxFileSize = Steam::phpBytes(ini_get('upload_max_filesize')); - $maxPostSize = Steam::phpBytes(ini_get('post_max_size')); + $maxFileSize = app('steam')->phpBytes(ini_get('upload_max_filesize')); + $maxPostSize = app('steam')->phpBytes(ini_get('post_max_size')); $uploadSize = min($maxFileSize, $maxPostSize); View::share('uploadSize', $uploadSize); @@ -109,8 +108,8 @@ class SingleController extends Controller $tags = join(',', $journal->tags()->get()->pluck('tag')->toArray()); /** @var Transaction $transaction */ $transaction = $journal->transactions()->first(); - $amount = Steam::positive($transaction->amount); - $foreignAmount = null === $transaction->foreign_amount ? null : Steam::positive($transaction->foreign_amount); + $amount = app('steam')->positive($transaction->amount); + $foreignAmount = null === $transaction->foreign_amount ? null : app('steam')->positive($transaction->foreign_amount); $preFilled = [ 'description' => $journal->description, @@ -158,7 +157,6 @@ class SingleController extends Controller { $what = strtolower($what); $what = $request->old('what') ?? $what; - $uploadSize = min(Steam::phpBytes(ini_get('upload_max_filesize')), Steam::phpBytes(ini_get('post_max_size'))); $assetAccounts = $this->groupedActiveAccountList(); $budgets = ExpandedForm::makeSelectListWithEmpty($this->budgets->getActiveBudgets()); $piggyBanks = $this->piggyBanks->getPiggyBanksWithAmount(); @@ -182,7 +180,7 @@ class SingleController extends Controller return view( 'transactions.single.create', - compact('assetAccounts', 'subTitleIcon', 'uploadSize', 'budgets', 'what', 'piggies', 'subTitle', 'optionalFields', 'preFilled') + compact('assetAccounts', 'subTitleIcon', 'budgets', 'what', 'piggies', 'subTitle', 'optionalFields', 'preFilled') ); } diff --git a/app/Http/Requests/BillFormRequest.php b/app/Http/Requests/BillFormRequest.php index b08c26279a..91535dc30e 100644 --- a/app/Http/Requests/BillFormRequest.php +++ b/app/Http/Requests/BillFormRequest.php @@ -53,6 +53,7 @@ class BillFormRequest extends Request 'skip' => $this->integer('skip'), 'automatch' => $this->boolean('automatch'), 'active' => $this->boolean('active'), + 'notes' => $this->string('notes'), ]; } diff --git a/app/Models/Bill.php b/app/Models/Bill.php index 866bfbf4d3..7b9a7fd2a7 100644 --- a/app/Models/Bill.php +++ b/app/Models/Bill.php @@ -74,6 +74,14 @@ class Bill extends Model throw new NotFoundHttpException; } + /** + * @return \Illuminate\Database\Eloquent\Relations\MorphMany + */ + public function attachments() + { + return $this->morphMany('FireflyIII\Models\Attachment', 'attachable'); + } + /** * @param $value * @@ -102,6 +110,14 @@ class Bill extends Model return $value; } + /** + * Get all of the notes. + */ + public function notes() + { + return $this->morphMany('FireflyIII\Models\Note', 'noteable'); + } + /** * @param $value */ diff --git a/app/Repositories/Bill/BillRepository.php b/app/Repositories/Bill/BillRepository.php index 3bce70f739..7b1491908e 100644 --- a/app/Repositories/Bill/BillRepository.php +++ b/app/Repositories/Bill/BillRepository.php @@ -25,6 +25,7 @@ namespace FireflyIII\Repositories\Bill; use Carbon\Carbon; use DB; use FireflyIII\Models\Bill; +use FireflyIII\Models\Note; use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionType; @@ -536,6 +537,11 @@ class BillRepository implements BillRepositoryInterface ] ); + // update note: + if (isset($data['notes'])) { + $this->updateNote($bill, $data['notes']); + } + return $bill; } @@ -558,6 +564,11 @@ class BillRepository implements BillRepositoryInterface $bill->active = $data['active']; $bill->save(); + // update note: + if (isset($data['notes']) && null !== $data['notes']) { + $this->updateNote($bill, strval($data['notes'])); + } + return $bill; } @@ -598,4 +609,32 @@ class BillRepository implements BillRepositoryInterface return $wordMatch; } + + + /** + * @param Bill $bill + * @param string $note + * + * @return bool + */ + protected function updateNote(Bill $bill, string $note): bool + { + if (0 === strlen($note)) { + $dbNote = $bill->notes()->first(); + if (null !== $dbNote) { + $dbNote->delete(); + } + + return true; + } + $dbNote = $bill->notes()->first(); + if (null === $dbNote) { + $dbNote = new Note(); + $dbNote->noteable()->associate($bill); + } + $dbNote->text = trim($note); + $dbNote->save(); + + return true; + } } diff --git a/app/Repositories/Journal/JournalRepository.php b/app/Repositories/Journal/JournalRepository.php index 9ede11c83a..e43bf02459 100644 --- a/app/Repositories/Journal/JournalRepository.php +++ b/app/Repositories/Journal/JournalRepository.php @@ -411,6 +411,7 @@ class JournalRepository implements JournalRepositoryInterface return $journal; } + /** * Same as above but for transaction journal with multiple transactions. * diff --git a/config/firefly.php b/config/firefly.php index 8e5e52fb05..3643b2c39e 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -35,7 +35,7 @@ return [ 'encryption' => (is_null(env('USE_ENCRYPTION')) || env('USE_ENCRYPTION') === true), 'version' => '4.6.11', 'maxUploadSize' => 15242880, - 'allowedMimes' => ['image/png', 'image/jpeg', 'application/pdf'], + 'allowedMimes' => ['image/png', 'image/jpeg', 'application/pdf','text/plain'], 'list_length' => 10, 'export_formats' => [ 'csv' => 'FireflyIII\Export\Exporter\CsvExporter', diff --git a/resources/views/bills/create.twig b/resources/views/bills/create.twig index 5ee65cf3c8..3f2701cbcd 100644 --- a/resources/views/bills/create.twig +++ b/resources/views/bills/create.twig @@ -6,7 +6,7 @@ {% block content %} -
+
@@ -32,9 +32,12 @@

{{ 'optionalFields'|_ }}

+ {{ ExpandedForm.textarea('notes',null,{helpText: trans('firefly.field_supports_markdown')}) }} + {{ ExpandedForm.file('attachments[]', {'multiple': 'multiple','helpText': trans('firefly.upload_max_file_size', {'size': uploadSize|filesize}) }) }} {{ ExpandedForm.integer('skip',0) }} {{ ExpandedForm.checkbox('automatch',1,true) }} {{ ExpandedForm.checkbox('active',1,true) }} +
diff --git a/resources/views/bills/edit.twig b/resources/views/bills/edit.twig index ee48b4375b..e2983cd929 100644 --- a/resources/views/bills/edit.twig +++ b/resources/views/bills/edit.twig @@ -6,7 +6,7 @@ {% block content %} - {{ Form.model(bill, {'class' : 'form-horizontal','id' : 'update','url' : route('bills.update', bill.id)}) }} + {{ Form.model(bill, {'class' : 'form-horizontal','enctype': 'multipart/form-data','id' : 'update','url' : route('bills.update', bill.id)}) }} @@ -34,6 +34,8 @@

{{ 'optionalFields'|_ }}

+ {{ ExpandedForm.textarea('notes',null,{helpText: trans('firefly.field_supports_markdown')}) }} + {{ ExpandedForm.file('attachments[]', {'multiple': 'multiple','helpText': trans('firefly.upload_max_file_size', {'size': uploadSize|filesize}) }) }} {{ ExpandedForm.integer('skip') }} {{ ExpandedForm.checkbox('automatch',1) }} {{ ExpandedForm.checkbox('active',1) }} diff --git a/resources/views/bills/show.twig b/resources/views/bills/show.twig index d233a6de8c..24846d11c4 100644 --- a/resources/views/bills/show.twig +++ b/resources/views/bills/show.twig @@ -24,7 +24,7 @@
- +
{{ 'matching_on'|_ }} @@ -84,12 +84,60 @@

{{ 'more'|_ }}

-
-

- {{ 'rescan_old'|_ }} -

+
+ {% if bill.notes.count == 1 %} + + + + + +
{{ trans('list.notes') }}{{ bill.notes.first.text|markdown }}
+ {% endif %} +
+ +
+ {% if bill.attachments|length > 0 %} +
+
+

{{ 'attachments'|_ }}

+
+
+ + {% for att in bill.attachments %} + + + + + + {% endfor %} +
+
+ + +
+
+ + + {% if att.title %} + {{ att.title }} + {% else %} + {{ att.filename }} + {% endif %} + + ({{ att.size|filesize }}) + {% if att.description %} +
+ {{ att.description }} + {% endif %} +
+ +
+
+
+ {% endif %} diff --git a/resources/views/list/bills.twig b/resources/views/list/bills.twig index d848470588..e532665d60 100644 --- a/resources/views/list/bills.twig +++ b/resources/views/list/bills.twig @@ -20,6 +20,11 @@
{{ entry.name }} + {# count attachments #} + {% if entry.attachments.count > 0 %} + + {% endif %} +