From afeefa5a7b088a0938898180adf4254479d90de0 Mon Sep 17 00:00:00 2001 From: Lumiware Date: Fri, 22 Feb 2019 12:33:12 +0100 Subject: [PATCH 1/2] Finished service approval UI + backend --- .../Controllers/ApproverPagesController.php | 88 ++++- .../ApproverSubscriptionController.php | 6 + .../ApproverUpdateSubscriptionRequest.php | 17 +- app/Models/Subscription.php | 20 +- app/Models/Transaction.php | 3 +- app/Providers/EventServiceProvider.php | 2 + .../EnsureSubscriptionApprovedAtColumnSet.php | 26 ++ .../Transformers/SubscriptionTransformer.php | 4 + app/User.php | 11 + ...e_and_id_column_to_subscriptions_table.php | 32 ++ public/js/approve-service-requests.js | 76 ++-- public/js/approve-trip-requests.js | 16 +- public/js/operator-activate-subscription.js | 6 +- public/js/operator-create-transaction.js | 6 +- .../lang/en/fe/approve-service-requests.php | 42 ++ .../lang/en/fe/approve-trip-requests.php | 6 +- .../lang/nl/fe/approve-service-requests.php | 44 +++ .../lang/nl/fe/approve-trip-requests.php | 6 +- .../includes/js-translations/en.blade.php | 4 + .../includes/js-translations/nl.blade.php | 4 + .../approve-service-requests.blade.php | 359 ++++++++++++------ .../approver/approve-trip-requests.blade.php | 9 +- .../Deletion/SubscriptionDeletionTest.php | 11 +- 23 files changed, 586 insertions(+), 212 deletions(-) create mode 100644 app/Subscriptions/Events/EnsureSubscriptionApprovedAtColumnSet.php create mode 100644 database/migrations/2019_02_21_134909_add_approver_motivation_and_date_and_id_column_to_subscriptions_table.php create mode 100644 resources/lang/en/fe/approve-service-requests.php create mode 100644 resources/lang/nl/fe/approve-service-requests.php diff --git a/app/Http/Controllers/ApproverPagesController.php b/app/Http/Controllers/ApproverPagesController.php index b8d7602adb56..99c16906c650 100644 --- a/app/Http/Controllers/ApproverPagesController.php +++ b/app/Http/Controllers/ApproverPagesController.php @@ -2,16 +2,82 @@ namespace App\Http\Controllers; +use App\Models\Subscription; use App\Models\Transaction; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class ApproverPagesController extends Controller { - public function getServiceRequests() + public function getServiceRequests(Request $request) { if ($this->checkApprover()) { - return view('pages.approver.approve-service-requests'); + // Get budgets for which the logged in user is the approver + $approver = Auth::user(); + $selectedSubscription = null; + + // Denotes whether a success alert should be shown, false by default + $success = ''; + $previousSubscriptionName = ''; + + // First, check if the previous operation was successful + if ($request->query('operation')) { + $success = $request->query('operation'); + $previousSubscriptionName = Subscription::findOrFailForOrganization($approver->organization->id, $request->query('previousSubscriptionId'))->internal_reference; + } + + // Get budgets managed by user + $managedBudgetIds = $approver->approverBudgets()->get()->pluck('id'); + + // Get 10 oldest subscriptions across all managed budgets + $subscriptionsToRate = Subscription::query() + ->whereIn('organization_budget_id', $managedBudgetIds) + ->where('status', Subscription::TO_BE_APPROVED) + ->orderBy('requested_on', 'ASC') + ->take(10) + ->get(); + + // Optional request parameter indicating the subscription that needs to be evaluated + $selectedSubscriptionId = $request->get('subscriptionId'); + + if ($selectedSubscriptionId) { + // Get info about selected subscription + $selectedSubscription = Subscription::findOrFailForOrganization($approver->organization->id, $selectedSubscriptionId); + // If the subscription is not included in the list, assign the first trip of the list as selected + if (!$subscriptionsToRate->contains('id', $selectedSubscriptionId)) { + $selectedSubscription = $subscriptionsToRate->first(); + } + } else { + // No selected transaction, assign first transaction as selected, if available + // If the list of transactions is empty, selectedTrip gets null assigned to it + $selectedSubscription = $subscriptionsToRate->first(); + } + + // Get additional information for selected trip + + // Budget of selected trip + $budget = null; + if ($selectedSubscription) { + $budget = $selectedSubscription->organizationBudget; + } + + // Show all other active or approved subscriptions for the user + $otherSubscriptions = null; + if ($selectedSubscription) { + $otherSubscriptions = Subscription::whereUserId($selectedSubscription->user_id) + ->whereIn('status', [Subscription::ACTIVE, Subscription::APPROVED]) + ->orderBy('end_on', 'ASC') + ->get(); + } + + // Show 10 oldest subscriptions to be approved + return view('pages.approver.approve-service-requests') + ->withSubscriptionsToRate($subscriptionsToRate) + ->withSelectedSubscription($selectedSubscription) + ->withBudget($budget) + ->withOtherSubscriptions($otherSubscriptions) + ->withSuccess($success) + ->withPreviousSubscriptionName($previousSubscriptionName); } return $this->getUserView(); @@ -26,12 +92,12 @@ public function getTripRequests(Request $request) // Denotes whether a success alert should be shown, false by default $success = ''; - $previousTransaction = ''; + $previousTransactionName = ''; // First, check if the previous operation was successful if ($request->query('operation')) { $success = $request->query('operation'); - $previousTransaction = $request->query('name'); + $previousTransactionName = Transaction::findOrFailForOrganization($approver->organization->id, $request->query('previousTransactionId'))->description; } // Get budgets managed by user @@ -50,13 +116,9 @@ public function getTripRequests(Request $request) if ($selectedTripId) { // Get info about selected transaction - $selectedTrip = Transaction::whereId($selectedTripId)->first(); - // If the transaction is included in the list, assign the selected trip - if ($selectedTrip && $tripsToRate->contains('id', $selectedTripId)) { - $selectedTrip = Transaction::whereId($selectedTripId)->first(); - } - // Otherwise, assign the first trip of the list as selected - else { + $selectedTrip = Transaction::findOrFailForOrganization($approver->organization->id, $selectedTripId); + // If the transaction is not included in the list, assign the first trip of the list as selected + if ($selectedTrip && !$tripsToRate->contains('id', $selectedTripId)) { $selectedTrip = $tripsToRate->first(); } } else { @@ -84,14 +146,14 @@ public function getTripRequests(Request $request) ->get(); } - // Show 10 oldest transactions + // Show 10 oldest transactions to be approved return view('pages.approver.approve-trip-requests') ->withTripsToRate($tripsToRate) ->withSelectedTrip($selectedTrip) ->withBudget($budget) ->withRecentTrips($recentTrips) ->withSuccess($success) - ->withPreviousTransaction($previousTransaction); + ->withPreviousTransactionName($previousTransactionName); } return $this->getUserView(); diff --git a/app/Http/Controllers/ApproverSubscriptionController.php b/app/Http/Controllers/ApproverSubscriptionController.php index 14f34a5c758a..85920fab3ef3 100644 --- a/app/Http/Controllers/ApproverSubscriptionController.php +++ b/app/Http/Controllers/ApproverSubscriptionController.php @@ -68,6 +68,12 @@ public function updateSubscription(ApproverUpdateSubscriptionRequest $request, s throw new AccessDeniedHttpException('Subscription cannot be approved by you.'); } $subscription->status = $request->getStatus(); //request already checked if valid status. + + // Set the approver for this transaction (approved or disapproved) + $subscription->approver()->associate($request->user()); + + $subscription->approver_motivation = $request->getApproverMotivation(); + $subscription->save(); return $subscription; diff --git a/app/Http/Requests/Users/ApproverUpdateSubscriptionRequest.php b/app/Http/Requests/Users/ApproverUpdateSubscriptionRequest.php index e8b708c2f5cf..55a339f48106 100644 --- a/app/Http/Requests/Users/ApproverUpdateSubscriptionRequest.php +++ b/app/Http/Requests/Users/ApproverUpdateSubscriptionRequest.php @@ -11,16 +11,23 @@ */ class ApproverUpdateSubscriptionRequest extends FormRequest { - /** status to set the transaction to. */ + public function rules() + { + return [ + 'status' => ['required', 'string', Rule::in([Transaction::DISAPPROVED, Transaction::APPROVED])], + 'approverMotivation' => ['nullable', 'string'], + ]; + } + + /** status to set the subscription to. */ public function getStatus(): string { return $this->get('status'); } - public function rules() + /** Text shown to user why a subscription request was disapproved (or approved). */ + public function getApproverMotivation() { - return [ - 'status' => ['required', 'string', Rule::in([Transaction::DISAPPROVED, Transaction::APPROVED])], - ]; + return $this->getValidated('approverMotivation'); } } diff --git a/app/Models/Subscription.php b/app/Models/Subscription.php index 45df3cea1a97..4aa5e516a777 100644 --- a/app/Models/Subscription.php +++ b/app/Models/Subscription.php @@ -20,20 +20,24 @@ * @property string $service * @property string $status * @property string $organization_budget_id - * @property string $requested_on + * @property \Carbon\Carbon|null $requested_on * @property string $user_id * @property string|null $internal_reference * @property \Carbon\Carbon|null $created_at * @property \Carbon\Carbon|null $updated_at - * @property string|null $deleted_at + * @property \Carbon\Carbon|null $deleted_at + * @property \Carbon\Carbon|null $approved_at * @property string|null $organization_id * @property array $payload * @property float|null $price * @property string|null $document_id + * @property string|null $approver_id + * @property string|null $approver_motivation * @property-read \App\Models\Organization|null $organization * @property-read \App\Models\OrganizationBudget $organizationBudget * @property-read \App\User $user * @property-read \App\Models\Document|null $document + * @property-read \App\User|null $approver * * @method static bool|null forceDelete() * @method static \Illuminate\Database\Query\Builder|\App\Models\Subscription onlyTrashed() @@ -144,6 +148,8 @@ class Subscription extends Model implements HasDeletionPolicy 'payload' => 'array', 'start_on' => 'datetime', 'end_on' => 'datetime', + 'requested_on' => 'datetime', + 'approved_on' => 'datetime', ]; /** @@ -189,6 +195,16 @@ public function document() return $this->belongsTo(Document::class)->withTrashed(); } + /** + * Get the user who is the approver for this subscription. + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function approver() + { + return $this->belongsTo(User::class)->withTrashed(); + } + /** * @param $organizationId * @param $subscriptionId diff --git a/app/Models/Transaction.php b/app/Models/Transaction.php index 2b518e24d411..e1abb6b50d67 100644 --- a/app/Models/Transaction.php +++ b/app/Models/Transaction.php @@ -26,7 +26,7 @@ * @property \Carbon\Carbon|null $created_at * @property \Carbon\Carbon|null $updated_at * @property \Carbon\Carbon|null $approved_at - * @property string|null $deleted_at + * @property \Carbon\Carbon|null $deleted_at * @property string|null $document_id * @property string|null $approver_id * @property string|null $approver_motivation @@ -124,6 +124,7 @@ class Transaction extends Model implements HasDeletionPolicy 'occurred_on' => 'datetime', 'created_on' => 'datetime', 'updated_on' => 'datetime', + 'approved_on' => 'datetime', ]; /** diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index dc82d9ae5897..557775548a97 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -8,6 +8,7 @@ use App\Subscriptions\Events\SubscriptionStatusChangedEvent; use App\Subscriptions\Events\SubscriptionStatusChangedObserver; use App\Transactions\EventHandlers\MailTransactionStatusOnChangedHandler; +use App\Transactions\Events\EnsureSubscriptionApprovedAtColumnSet; use App\Transactions\Events\EnsureTransactionApprovedAtColumnSet; use App\Transactions\Events\InstantAutoApproveTransactionObserver; use App\Transactions\Events\TransactionStatusChangedEvent; @@ -44,6 +45,7 @@ public function boot() Transaction::observe(TransactionStatusChangedObserver::class); Transaction::observe(EnsureTransactionApprovedAtColumnSet::class); Subscription::observe(SubscriptionStatusChangedObserver::class); + Subscription::observe(EnsureSubscriptionApprovedAtColumnSet::class); parent::boot(); } } diff --git a/app/Subscriptions/Events/EnsureSubscriptionApprovedAtColumnSet.php b/app/Subscriptions/Events/EnsureSubscriptionApprovedAtColumnSet.php new file mode 100644 index 000000000000..d42c9c0f61f9 --- /dev/null +++ b/app/Subscriptions/Events/EnsureSubscriptionApprovedAtColumnSet.php @@ -0,0 +1,26 @@ +check($model); + } + + public function updating(Subscription $model) + { + $this->check($model); + } + + private function check(Subscription $subscription) + { + if (Subscription::APPROVED === $subscription->status && null === $subscription->approved_at) { + $subscription->approved_at = Carbon::now(); + } + } +} diff --git a/app/Subscriptions/Transformers/SubscriptionTransformer.php b/app/Subscriptions/Transformers/SubscriptionTransformer.php index d70691f021ef..647a23772112 100644 --- a/app/Subscriptions/Transformers/SubscriptionTransformer.php +++ b/app/Subscriptions/Transformers/SubscriptionTransformer.php @@ -36,6 +36,10 @@ public function transform(Subscription $subscription) 'payload' => $subscription->payload, 'userId' => $subscription->user_id, 'budgetId' => $subscription->organization_budget_id, + 'documentId' => $subscription->document_id, + 'approverMotivation' => $subscription->approver_motivation, + 'approvedAt' => $subscription->approved_at, + 'approverId' => $subscription->approver_id, ]; } diff --git a/app/User.php b/app/User.php index 6412152e8427..cd8d2d2d26aa 100644 --- a/app/User.php +++ b/app/User.php @@ -54,6 +54,7 @@ * @property-read \App\Models\Organization|null $organization * @property-read \App\Models\OrganizationRole|null $role * @property-read \App\Models\Subscription[]|\Illuminate\Database\Eloquent\Collection $subscriptions + * @property-read \App\Models\Transaction[]|\Illuminate\Database\Eloquent\Collection $subscriptionsApprovedByMe * @property-read \App\Models\Transaction[]|\Illuminate\Database\Eloquent\Collection $transactionsApprovedByMe * @property-read \Illuminate\Database\Eloquent\Collection|\Laravel\Passport\Token[] $tokens * @property-read \App\Models\OrganizationBudget[]|\Illuminate\Database\Eloquent\Collection $isApproverFor @@ -166,6 +167,16 @@ public function subscriptions() return $this->hasMany(Subscription::class); } + /** + * Get subscriptions approved by user. + * + * @return \Illuminate\Database\Eloquent\Relations\HasMany + */ + public function subscriptionsApprovedByMe() + { + return $this->hasMany(Subscription::class, 'approver_id'); + } + /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ diff --git a/database/migrations/2019_02_21_134909_add_approver_motivation_and_date_and_id_column_to_subscriptions_table.php b/database/migrations/2019_02_21_134909_add_approver_motivation_and_date_and_id_column_to_subscriptions_table.php new file mode 100644 index 000000000000..82e029363a89 --- /dev/null +++ b/database/migrations/2019_02_21_134909_add_approver_motivation_and_date_and_id_column_to_subscriptions_table.php @@ -0,0 +1,32 @@ +timestamp('approved_at')->nullable()->after('deleted_at'); + $table->string('approver_id')->after('document_id')->nullable(); + $table->string('approver_motivation')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down() + { + Schema::table('subscriptions', function (Blueprint $table) { + $table->dropColumn('approver_motivation'); + $table->dropColumn('approver_id'); + $table->dropColumn('approved_at'); + }); + } +} diff --git a/public/js/approve-service-requests.js b/public/js/approve-service-requests.js index 6f21ce0a3625..f8642a31ad85 100644 --- a/public/js/approve-service-requests.js +++ b/public/js/approve-service-requests.js @@ -1,44 +1,38 @@ -// Selectors -var $errorAlert = $('#error-message'); +function disapproveServiceRequest() { + var subscriptionId = $('#decisionBox').data('subscription-id'); + var subscriptionName = $('#decisionBox').data('subscription-name'); + var motivationText = $('#decisionMotivation').val(); -$(function () { - $("#submit-TokenRequest").on('click', function (e) { - e.preventDefault(); - var clientid = $('#clientId').val(); - var clientSecret = $('#clientSecret').val(); - $.ajax({ - url: '/api/oauth/token', - data: JSON.stringify({ - "grant_type": "client_credentials", - "scope": "*", - "client_id": clientid - }), - method: 'POST', - headers: { - 'Authorization': 'Basic ' + btoa(clientid + ':' + clientSecret), - 'Accept': 'application/json', - 'Content-Type': 'application/json', - 'scope': '*' - } - }) - .done(function (result) { - e.preventDefault(); - var token = result.access_token; - setCookie('operator-auth', token, 1); - $("#auth-form").hide(); + var data = {status: 'disapproved', approverMotivation: motivationText}; - apiCall('api/organizations', 'GET') - .done(function (result) { - $("#approver-overview").show(); + // After, send the API call for the service request creation. + apiCall('/api/users/me/approvers/subscriptions/' + subscriptionId, 'PATCH', data, + // On success + function () { + // Show alert for success upon reload + location.href = "?operation=disapproved&previousSubscriptionId=" + subscriptionId; + }, + // On fail + function (data) { + $('#error-message').html('
' + approveServiceRequests.subscriptionUpdateError + ': '+ data.responseJSON.message + '
'); + }); +} - }).fail(function (result) { - var errorMessage = 'An error has occurred.'; - $errorAlert.html('
' + errorMessage + '
'); - }) - }) - .fail(function () { - var errorMessage = 'An error has occurred.'; - $errorAlert.html('
' + errorMessage + '
'); - }); - }); -}); \ No newline at end of file +function approveServiceRequest() { + var subscriptionId = $('#decisionBox').data('subscription-id'); + var motivationText = $('#decisionMotivation').val(); + + var data = {status: 'approved', approverMotivation: motivationText}; + + // After, send the API call for the service request creation. + apiCall('/api/users/me/approvers/subscriptions/' + subscriptionId, 'PATCH', data, + // On success + function () { + // Show alert for success upon reload + location.href = "?operation=approved&previousSubscriptionId=" + subscriptionId; + }, + // On fail + function (data) { + $('#error-message').html('
' + approveServiceRequests.subscriptionUpdateError + '
'+ data.responseJSON.message + '
'); + }); +} \ No newline at end of file diff --git a/public/js/approve-trip-requests.js b/public/js/approve-trip-requests.js index 6bd58c0630eb..bedf8082d294 100644 --- a/public/js/approve-trip-requests.js +++ b/public/js/approve-trip-requests.js @@ -1,15 +1,15 @@ function disapproveTripRequest() { - // Check if the user has checked the agreement box var transactionId = $('#decisionBox').data('transaction-id'); - var transactionName = $('#decisionBox').data('transaction-name'); var motivationText = $('#decisionMotivation').val(); + var data = {status: 'disapproved', approverMotivation: motivationText}; + // After, send the API call for the service request creation. - apiCall('/api/users/me/approvers/transactions/' + transactionId, 'PATCH', {status: 'disapproved', approverMotivation: motivationText}, + apiCall('/api/users/me/approvers/transactions/' + transactionId, 'PATCH', data, // On success function () { // Show alert for success upon reload - location.href = "?operation=disapproved&name=" + transactionName; + location.href = "?operation=disapproved&previousTransactionId=" + transactionId; }, // On fail function (data) { @@ -18,17 +18,17 @@ function disapproveTripRequest() { } function approveTripRequest() { - // Check if the user has checked the agreement box var transactionId = $('#decisionBox').data('transaction-id'); - var transactionName = $('#decisionBox').data('transaction-name'); var motivationText = $('#decisionMotivation').val(); + var data = {status: 'approved', approverMotivation: motivationText}; + // After, send the API call for the service request creation. - apiCall('/api/users/me/approvers/transactions/' + transactionId, 'PATCH', {status: 'approved', approverMotivation: motivationText}, + apiCall('/api/users/me/approvers/transactions/' + transactionId, 'PATCH', data, // On success function () { // Show alert for success upon reload - location.href = "?operation=approved&name=" + transactionName; + location.href = "?operation=approved&previousTransactionId=" + transactionId; }, // On fail function (data) { diff --git a/public/js/operator-activate-subscription.js b/public/js/operator-activate-subscription.js index 1abf25c04c98..255e36fc7afa 100644 --- a/public/js/operator-activate-subscription.js +++ b/public/js/operator-activate-subscription.js @@ -319,5 +319,9 @@ $fileUpload.change(function () { $docId.val(result.data.id); $docId.show(); // $fileUpload.hide(); - }).fail(console.error); + }).fail(function(error){ + console.log(error) + var errorMessage = 'An error has occurred: the attachment file is too large'; + $errorAlert.html('
' + errorMessage + '
'); + }); }); diff --git a/public/js/operator-create-transaction.js b/public/js/operator-create-transaction.js index 2a4cf2721aed..32c128ead3a6 100644 --- a/public/js/operator-create-transaction.js +++ b/public/js/operator-create-transaction.js @@ -328,5 +328,9 @@ $fileUpload.change(function () { $docId.val(result.data.id); $docId.show(); // $fileUpload.hide(); - }).fail(console.error); + }).fail(function(error){ + console.log(error) + var errorMessage = 'An error has occurred: the attachment file is too large'; + $errorAlert.html('
' + errorMessage + '
'); + }); }); diff --git a/resources/lang/en/fe/approve-service-requests.php b/resources/lang/en/fe/approve-service-requests.php new file mode 100644 index 000000000000..417064977fcd --- /dev/null +++ b/resources/lang/en/fe/approve-service-requests.php @@ -0,0 +1,42 @@ + 'Approve service requests', + + 'title' => 'Approver panel - Service requests', + 'lead' => 'On this page you can evaluate incoming service requests for which you are the approver.
+ These trips did not qualify for instant approval, a manual review is required.', + + 'alert-approved' => 'The subscription :subscriptionName has been approved successfully.', + 'alert-disapproved' => 'The subscription :subscriptionName has been disapproved successfully.', + + 'service-requests-title' => 'Service requests', + 'no-requests-text' => 'All clear! No subscriptions are awaiting approval at the moment.', + + 'no-requests-title' => 'No service requests filed', + 'no-requests-explanation' => 'There are no service requests for the budgets that you can approve. Once a subscription requires a manual review, they will show up here.', + + 'service-request-details-title' => 'Details for service request', + 'service-request-details-subtitle' => 'Subscription details', + 'table-requester' => 'Requester', + 'table-service' => 'Service name', + 'table-description' => 'Description', + 'table-cost' => 'Cost', + 'table-budget' => 'Assigned budget', + 'table-reason' => 'Reason for manual review', + 'table-reason-ph' => 'Unspecified', + + 'service-overview-title' => 'Other active subscription for user', + 'no-services-text' => 'No other subscriptions were active prior to this service request.', + + 'budget-info-title' => 'Information about budget:', + 'budget-amount' => 'Budget amount', + 'budget-approve-limit' => 'Instant approve amount limit', + 'budget-monthly-limit' => 'Monthly limit for instant approve', + 'budget-trip-approved-after' => 'Trips for this subscription will be auto approved after', + 'unknown' => 'Unknown', + + 'motivation-label' => 'Motivation (optional)', + 'btn-disapprove-text' => 'Disapprove', + 'btn-approve-text' => 'Approve service request', +]; \ No newline at end of file diff --git a/resources/lang/en/fe/approve-trip-requests.php b/resources/lang/en/fe/approve-trip-requests.php index 8867e16664a7..75283534b94c 100644 --- a/resources/lang/en/fe/approve-trip-requests.php +++ b/resources/lang/en/fe/approve-trip-requests.php @@ -7,10 +7,8 @@ 'lead' => 'On this page you can evaluate incoming trip requests for which you are the approver.
These trips did not qualify for instant approval, a manual review is required.', - 'alert-approved-1' => 'The trip', - 'alert-approved-2' => 'has been approved successfully.', - 'alert-disapproved-1' => 'The trip', - 'alert-disapproved-2' => 'has been disapproved successfully.', + 'alert-approved' => 'The trip :tripName has been approved successfully.', + 'alert-disapproved' => 'The trip :tripName has been disapproved successfully.', 'trip-requests-title' => 'Trip requests', 'no-requests-text' => 'All clear! No trips are awaiting approval at the moment.', diff --git a/resources/lang/nl/fe/approve-service-requests.php b/resources/lang/nl/fe/approve-service-requests.php new file mode 100644 index 000000000000..cc59f657e92d --- /dev/null +++ b/resources/lang/nl/fe/approve-service-requests.php @@ -0,0 +1,44 @@ + 'Service verzoeken', + + 'title' => 'Beheerdersconcole - Service verzoeken', + 'lead' => 'Op deze pagina kan je binnenkomende service verzoeken evalueren voor de budgets waarvan je de approver bent.
+ Deze subscriptions voldoen niet aan de voorwaarden voor instant-goedkeuring, een manuele evaluatie is nodig.', + + 'alert-approved' => 'De subscription :subscriptionName werd succesvol goedgekeurd.', + 'alert-disapproved' => 'De subscription :subscriptionName werd succesvol afgekeurd.', + + 'service-requests-title' => 'Service verzoeken', + 'no-requests-text' => 'In orde! Momenteel zijn er geen openstaande service verzoeken.', + + 'no-requests-title' => 'Geen openstaande service verzoeken', + 'no-requests-explanation' => 'Momenteel zijn er geen openstaande service verzoeken op de budgetten die je beheert. Wanneer een service een manuele review vereist, zal deze hier verschijnen.', + + 'service-request-details-title' => 'Details voor service verzoek', + 'service-request-details-subtitle' => 'Subscription details', + 'table-requester' => 'Aanvrager', + 'table-service' => 'Service naam', + 'table-description' => 'Omschrijving', + 'table-cost' => 'Kostprijs', + 'table-budget' => 'Toegekend aan budget', + 'table-reason' => 'Reden voor manuele review', + 'table-reason-ph' => 'Niet gespecifieerd', + + 'service-overview-title' => 'Andere actieve subscriptions voor deze gebruiker', + 'no-services-text' => 'Geen andere subscriptions waren actief bij het aanvragen van deze service.', + + 'budget-info-title' => 'Budget informatie:', + 'budget-amount' => 'Budget bedrag', + 'budget-approve-limit' => 'Instant-goedkeuring bedrag limiet', + 'budget-monthly-limit' => 'Maandelijkse limiet voor instant-goedkeuring', + 'budget-trip-approved-after' => 'Trips voor subscription auto-goedgekeurd na', + 'unknown' => 'Onbekend', + + 'motivation-label' => 'Motivatie (optioneel)', + 'btn-disapprove-text' => 'Afkeuren', + 'btn-approve-text' => 'Goedkeuren van service verzoek', + + // {{ __('fe/approve-service-requests.') }} +]; \ No newline at end of file diff --git a/resources/lang/nl/fe/approve-trip-requests.php b/resources/lang/nl/fe/approve-trip-requests.php index 51fd7f09a4e7..f266b83e1d35 100644 --- a/resources/lang/nl/fe/approve-trip-requests.php +++ b/resources/lang/nl/fe/approve-trip-requests.php @@ -7,10 +7,8 @@ 'lead' => 'Op deze pagina kan je binnenkomende trip verzoeken evalueren voor de budgets waarvan je de approver bent.
Deze trips voldoen niet aan de voorwaarden voor instant-goedkeuring, een manuele evaluatie is nodig.', - 'alert-approved-1' => 'De trip', - 'alert-approved-2' => 'werd succesvol goedgekeurd.', - 'alert-disapproved-1' => 'De trip', - 'alert-disapproved-2' => 'werd succesvol afgekeurd.', + 'alert-approved' => 'De trip :tripName werd succesvol goedgekeurd.', + 'alert-disapproved' => 'De trip :tripName werd succesvol afgekeurd.', 'trip-requests-title' => 'Trip verzoeken', 'no-requests-text' => 'In orde! Momenteel zijn er geen openstaande trip verzoeken.', diff --git a/resources/views/includes/js-translations/en.blade.php b/resources/views/includes/js-translations/en.blade.php index 459f6d78428d..4d3b80ba3854 100644 --- a/resources/views/includes/js-translations/en.blade.php +++ b/resources/views/includes/js-translations/en.blade.php @@ -46,6 +46,10 @@ transactionUpdateError: 'Oops! An error has occurred while updating the trip.', }; + var approveServiceRequests = { + subscriptionUpdateError: 'Oops! An error has occurred while updating the subscription.', + }; + var bparkingTranslations = { ticketUploadSuccessMessage: 'Ticket photo uploaded. It might take a while until the trip will appear in My Trips.', ticketUploadOnlyImageError: 'It\'s only possible to upload tickets photos in png, jpeg, gif or tiff format.', diff --git a/resources/views/includes/js-translations/nl.blade.php b/resources/views/includes/js-translations/nl.blade.php index a05c7784341f..0c3430111037 100644 --- a/resources/views/includes/js-translations/nl.blade.php +++ b/resources/views/includes/js-translations/nl.blade.php @@ -46,6 +46,10 @@ transactionUpdateError: 'Oeps! Er ging iets mis bij het updaten van de trip.', }; + var approveServiceRequests = { + subscriptionUpdateError: 'Oeps! Er ging iets mis bij het updaten van de subscription.', + }; + var bparkingTranslations = { ticketUploadSuccessMessage: 'Ticket foto is geupload. Het kan even duren voordat deze verschijnt bij Mijn Trips.', ticketUploadOnlyImageError: 'Het is alleen mogelijk foto\'s te uploaden in het formaat: png, jpeg, gif of tiff.' diff --git a/resources/views/pages/approver/approve-service-requests.blade.php b/resources/views/pages/approver/approve-service-requests.blade.php index c72a6c682c61..7e2dda3ef38b 100644 --- a/resources/views/pages/approver/approve-service-requests.blade.php +++ b/resources/views/pages/approver/approve-service-requests.blade.php @@ -1,165 +1,274 @@ @extends('layouts.approver-default') -@section('title', 'Service requests') +@section('title', __('fe/approve-service-requests.tab-title')) @section('content') -

Approver panel - Service requests

-

On this page you can evaluate incoming service requests for which you are the approver.

-
+

{{ __('fe/approve-service-requests.title') }}

+

{!! __('fe/approve-service-requests.lead') !!}

- + @if($success == 'approved') +
{{ __('fe/approve-service-requests.alert-approved', ['subscriptionName' => $previousSubscriptionName]) }}
+ @endif + + @if($success == 'disapproved') +
{{ __('fe/approve-service-requests.alert-disapproved', ['subscriptionName' => $previousSubscriptionName]) }}
+ @endif -
+
- -
-
-
-
- Details for service request - Bike to work (structural) -
+
+ @if($subscriptionsToRate->count() === 0) +
+
+
+ {{ __('fe/approve-service-requests.no-requests-title') }} +
+
+
+ {{ __('fe/approve-service-requests.no-requests-explanation') }} +
-
-
User details
-
-
- Name -
-
- Home address -
-
- Work address -
+ @else + + @php $subscriber = $subscription->user; + $subscriptionInfo = $subscription->getMobilityServiceInformation(); + @endphp +
+
+
+ {{ __('fe/approve-service-requests.service-request-details-title') }} +
-
-
- Bert Turner +
+
{{ __('fe/approve-service-requests.service-request-details-subtitle') }}
+
+
+ {{ __('fe/approve-service-requests.table-requester') }} +
+
+ {{ __('fe/approve-service-requests.table-service') }} +
+
+ {{ __('fe/approve-service-requests.table-description') }} +
-
- Stationsstraat 32, 3150 Haacht +
+
+ {{$subscriber->first_name}} {{$subscriber->last_name}} +
+
+ {{$subscriptionInfo->name}} +
+
+ {{$subscription->internal_reference}} +
+
+
+
+ {{ __('fe/approve-service-requests.table-cost') }} +
+
+ {{ __('fe/approve-service-requests.table-budget') }} +
+
+ {{ __('fe/approve-service-requests.table-reason') }} +
-
- Herbert Hooverplein 23, 3000 Leuven +
+
+ € @money($subscription->price) +
+
+ {{$budget->name}} +
+
+ {{ __('fe/approve-service-requests.table-reason-ph') }} +
-
- -
-
Services already available to user
-
-
+
+
{{ __('fe/approve-service-requests.service-overview-title') }}
+ @if($otherSubscriptions->count() === 0)
-
NMBS Half-time season ticket
- Trajectory: Haacht - Leuven
- Class: 2nd
- Cost: €25 for 10 trips
- Expires at: 01/05/2019 +

{{ __('fe/approve-service-requests.no-services-text') }}

+ @else +
+ @foreach($otherSubscriptions as $otherSubscription) + @php $subscriptionInfo = $otherSubscription->getMobilityServiceInformation() @endphp +
+
+
+
+
+
{{$subscriptionInfo->name}}
+ @if($otherSubscription->status === \App\Models\Subscription::ACTIVE) + Active + @else + Approved + @endif +
+ {{$otherSubscription->internal_reference}} +
+
+ {{$subscriptionInfo->key}} logo + €@money($otherSubscription->price) +
+
+
+
+
+ @endforeach +
+ @endif +
+
{{ __('fe/approve-service-requests.budget-info-title') }} {{$budget->name}}
+
+
+ {{ __('fe/approve-service-requests.budget-amount') }} +
+
+ {{ __('fe/approve-service-requests.budget-approve-limit') }} +
+
+ {{ __('fe/approve-service-requests.budget-monthly-limit') }} +
+
+ {{ __('fe/approve-service-requests.budget-trip-approved-after') }} +
-
-
-
-
Blue-bike subscription
- Cost: €12/year, €1.15 per day used
- Expires at: 01/09/2019 -
+
+
+ @if($budget->budget) + € @money($budget->budget) + @else + {{ __('fe/approve-service-requests.unknown') }} + @endif +
+
+ @if($budget->instant_approve_transaction_limit) + € @money($budget->instant_approve_transaction_limit) + @else + {{ __('fe/approve-service-requests.unknown') }} + @endif +
+
+ @if($budget->instant_approve_monthly_limit) + € @money($budget->instant_approve_monthly_limit) + @else + {{ __('fe/approve-service-requests.unknown') }} + @endif +
+
+ @if($budget->auto_approve_after) + {{$budget->auto_approve_after}} + @else + {{ __('fe/approve-service-requests.unknown') }} + @endif
- -
-
Distance calculation
-
-
-

The estimated distance for biking from home to work is equal to: 19.1 km.

- - - + -
- -
- - @stop @section('page-scripts') - + -@stop +@stop \ No newline at end of file diff --git a/resources/views/pages/approver/approve-trip-requests.blade.php b/resources/views/pages/approver/approve-trip-requests.blade.php index 29cf745fe76f..c638b848c4bd 100644 --- a/resources/views/pages/approver/approve-trip-requests.blade.php +++ b/resources/views/pages/approver/approve-trip-requests.blade.php @@ -7,13 +7,11 @@

{!! __('fe/approve-trip-requests.lead') !!}

@if($success == 'approved') -
{{ __('fe/approve-trip-requests.alert-approved-1') }} - "{{$previousTransaction}}" {{ __('fe/approve-trip-requests.alert-approved-2') }}
+
{{ __('fe/approve-trip-requests.alert-approved', ['tripName' => $previousTransactionName]) }}
@endif @if($success == 'disapproved') -
{{ __('fe/approve-trip-requests.alert-disapproved-1') }} - "{{$previousTransaction}}" {{ __('fe/approve-trip-requests.alert-disapproved-2') }}
+
{{ __('fe/approve-trip-requests.alert-disapproved', ['tripName' => $previousTransactionName]) }}
@endif
@@ -238,8 +236,7 @@ class="list-group-item list-group-item-action"
-