Browse Source

Create user and create user order

Samson Mutunga 1 năm trước cách đây
mục cha
commit
c93a1bea7e

+ 15 - 0
app/Helpers.php

@@ -263,4 +263,19 @@ if(!function_exists('friendly_timezone')) {
         }
     }
 }
+if (!function_exists('generate_password')) {
+    function generate_password($length = 20)
+    {
+        $chars =  'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' .
+            '0123456789`-=~!@#$%^&*()_+,./<>?;:[]{}\|';
+
+        $str = '';
+        $max = strlen($chars) - 1;
+
+        for ($i = 0; $i < $length; $i++)
+            $str .= $chars[random_int(0, $max)];
+
+        return $str;
+    }
+}
 ?>

+ 77 - 0
app/Http/Controllers/AdminController.php

@@ -306,4 +306,81 @@ class AdminController extends Controller
         }
         return implode("", $output);
     }
+
+    public function orderCreate(Request $request){
+        $userUid = $request->get('userUid');
+        $allTests = config('constants.tests');
+        $selectedTests = $request->get('tests', []);
+        if(!count($selectedTests)){
+            return $this->fail('Please select a test!');
+        }
+        $tests = [];
+        foreach($allTests as $key=>$title){
+            $tests[$key] = in_array($key, $selectedTests) ? 1 : 0;
+        }
+        $data = [
+            'tests' => $tests,
+            'tests_total' => $request->get('total'),
+            'tests_lab_id' => $request->get('tests_lab_id')
+        ];
+
+        $detailJson = [
+            'selected_options' => json_encode($data)
+        ];
+
+        $javaResponse = $this->callJava('/api/customerStore/submitOrderAsAdmin', ['userUid' => $userUid, 'detailJson' => json_encode($detailJson)], $this->sessionKey);
+        if (!@$javaResponse['success']) {
+            return $this->fail($javaResponse['message']);
+        }
+        return $this->pass();
+    }
+
+    public function createNewUser(Request $request){
+        $email = $request->get('email');
+        $existingUser = User::where('email', $email)->first();
+        if ($existingUser) {
+        return $this->fail('This email account is in use!');
+        }
+        $nameFirst = $request->get('fname');
+        $nameLast = $request->get('lname');
+        $name = $nameFirst . ' ' . $nameLast;
+        //call java
+        $temporaryPassword = generate_password(10);
+
+        $userCreateAccountResponse = $this->callJava('/api/auth/signUpWithEmail', [
+        'fullName' => $name,
+        'nameFirst' => $nameFirst,
+        'nameLast' => $nameLast,
+        'email' => $request->get('email'),
+        'phoneNumber' => $request->get('phoneNumber'),
+        'password' => $temporaryPassword,
+        'passwordConfirmation' => $temporaryPassword,
+        ], null);
+
+        if (!@$userCreateAccountResponse['success']) {
+            return $this->fail($userCreateAccountResponse['message']);
+        }
+
+        $newUser = User::where('uid', $userCreateAccountResponse['data'])->first();
+
+        //Send email via java
+        if ($newUser) {
+          $this->emailService->sendUserWelcomeEmail($newUser, $temporaryPassword);
+        }
+        $this->storeUserDetailJson($request, $newUser);
+
+        return $this->pass($userCreateAccountResponse['data']);
+    }
+
+    public function storeUserDetailJson(Request $request, User $user)
+  {
+    $data = [
+      'uid' => $user->uid,
+      'phone_number' => $request->get('phoneNumber'),
+      'notification_option' => $request->get('notificationOption'),
+      'request_change_password' => 1,
+    ];
+
+    $res = $this->callJava('/api/user/upsertDetailJson', $data, $this->sessionKey);
+  }
 }

+ 24 - 0
app/Http/Services/EmailService.php

@@ -143,4 +143,28 @@ class EmailService
 
         $response = $this->callJava('/api/email/send', $params, null);
     }
+
+    public function sendUserWelcomeEmail(User $user, $temporaryPassword = null)
+    {
+        if (!$user->getEmail()) return;
+        $appInternalName = $this->appInternalName;
+        $stringMappingConfig = $this->stringMappingConfig;
+        $appUrl = $this->appUrl;
+        $emailFromName = $this->emailFromName;
+        $html = (string) view('emails.templates.user-welcome', compact('user', 'appUrl', 'emailFromName', 'appInternalName', 'stringMappingConfig', 'temporaryPassword'));
+        $plainText = (string) view('emails.templates.user-welcome-txt', compact('user', 'appUrl', 'emailFromName', 'appInternalName', 'stringMappingConfig', 'temporaryPassword'));
+
+        $params = [
+            'fromEmailAddress' => $this->fromEmailAddress,
+            'fromName' => $this->emailFromName,
+            'toEmailAddress' => $user->getEmail(),
+            'subject' => 'Welcome!',
+            'contentHtml' => $html,
+            'contentText' => $plainText,
+            'entityType' => 'USER',
+            'entityUid' => $user->uid,
+        ];
+
+        $response = $this->callJava('/api/email/send', $params, null);
+    }
 }

+ 96 - 0
resources/views/app/my-account/admin/orders/forms/create-order.blade.php

@@ -0,0 +1,96 @@
+<?php
+    $tests = config('constants.tests');
+    $packages = array_filter(
+        $tests,
+        function ($value){
+            return(strpos($value,'Test Panel') !== false);
+        }
+    );
+    $individualTests = array_diff($tests, $packages);
+?>
+<div moe normal>
+    <a start show href="#">+ Create Order</a>
+    <form url="{{ route('admin.create-order') }}" style="min-width: 450px;" right>
+        @csrf
+        <div class="p-3">
+            <h5 class="fw-bold mb-4">Create Order</h5>
+            <div id="createOrder" v-cloak>
+                <input type="hidden" name="total" v-model="form.total" />
+                <input type="hidden" name="userUid" value="{{$user->uid}}" />
+                <div class="form-group mb-3">
+                    <label class="me-3"><input type="radio" name="testType" value="11PanelTest" v-model="form.testType" required /> Comprehensive 11-Panel Test</label>
+                    <label><input type="radio" name="testType" value="individualTests" v-model="form.testType" required /> Individual Tests</label>
+                </div>
+                <div v-if="form.testType === '11PanelTest'" class="px-3">
+                    <div class="d-flex flex-column">
+                        @foreach($packages as $key=>$title)
+                            <label><input type="radio" name="tests[]" value="{{ $key }}" data-amount="{{ config('app.'.$key) }}" required /> {{ $title }} - {{ displayAmount('$', config('app.'.$key)) }}</label>
+                        @endforeach
+                    </div>
+                </div>
+                <div v-if="form.testType === 'individualTests'" class="px-3">
+                    <div class="d-flex flex-column">
+                        @foreach($individualTests as $k=>$t)
+                            <label><input type="checkbox" name="tests[]" value="{{ $k }}" data-amount="{{  config('app.'.$k) }}" /> {{ $t }} - {{ displayAmount('$', config('app.'.$k)) }}</label>
+                        @endforeach
+                    </div>
+                </div>
+                <div v-if="form.total" class="mt-3">
+                    Total: <b>$@{{ form.total }}</b>
+                </div>
+
+                
+
+            </div>
+            <div class="mt-4">
+                <button submit class="btn btn-sm btn-primary me-2">Create Order</button>
+                <button cancel class="btn btn-sm btn-default border">Cancel</button>
+            </div>
+        </div>
+    </form>
+</div>
+
+<script>
+    var createOrderComponent = new Vue({
+        el: '#createOrder',
+        data:{
+            form: {
+              total: 0  
+            },
+            
+        },
+        delimiters: ['@{{', '}}'],
+        methods:{
+            initCalculateTotal: function(){
+                var self = this;
+                $('[name=testType]').change(function(evt){
+                    self.form.total = 0;
+                });
+                $('[data-amount]').change(function(evt){
+                    var total = 0;
+                    var fields = $('[data-amount]');
+                    $.each(fields, function(index, field){
+                        var checked = field.checked ? true:false;
+                        var amount = $(field).data('amount');
+                        if(checked){
+                            total = total + amount;
+                        }
+                    });
+                    self.form.total = total;
+                });
+            },
+            init: function(){
+                
+            }
+        },
+        mounted: function(){
+            this.init();
+        },
+        updated: function(){
+            var self = this;
+            self.$nextTick(function(){
+                self.initCalculateTotal();
+            });
+        }
+    });
+</script>

+ 37 - 32
resources/views/app/my-account/admin/users/forms/create.blade.php

@@ -1,41 +1,46 @@
 <div moe relative>
     <a start show href="#">+ New User</a>
-    <form url="/api/affiliate/createCustomerAsReseller">
+    <form url="{{ route('admin.create-new-user') }}" redir="/admin/users/view/[data]/orders">
         <h4 class="fw-bold mb-4">New User</h4>
-        <div class="mb-3">
-            <label class="text-sm text-secondary mb-1">Coupon</label>
-            <?php $coupons = \App\Models\PromoCode::orderBy('code', 'ASC')->get(); ?>
-            <select name="promoCodeUid" class="form-control form-control-sm" required>
-                <option value="">-- select --</option>
-                @foreach($coupons as $coupon)
-                    <option value="{{$coupon->uid}}">{{$coupon->code}}</option>
-                @endforeach
-            </select>
-        </div>
-        <div class="mb-2">
-            <label class="text-sm text-secondary mb-1">First Name</label>
-            <input type="text" name="nameFirst" class="form-control form-control-sm" required onkeyup="generateFullName(this)">
-        </div>
-        <div class="mb-2">
-            <label class="text-sm text-secondary mb-1">Last Name</label>
-            <input type="text" name="nameLast" class="form-control form-control-sm" required onkeyup="generateFullName(this)">
-        </div>
-        <input type="hidden" name="fullName">
-        <div class="mb-2">
-            <label class="text-sm text-secondary mb-1">Email Address</label>
-            <input type="email" name="email" class="form-control form-control-sm" required>
-        </div>
-        <div class="mb-2">
-            <label class="text-sm text-secondary mb-1">Temporary Password</label>
-            <input type="password" name="temporaryPassword" class="form-control form-control-sm" required>
-        </div>
-        <div class="mb-3">
-            <label class="text-sm text-secondary mb-1">Welcome Message</label>
-            <textarea name="welcomeMessage" class="form-control form-control-sm" rows="2"></textarea>
+        <div id="createNewUser" v-cloak>
+            <div class="mb-2">
+                <label class="text-sm text-secondary mb-1">First Name*</label>
+                <input type="text" name="fname" class="form-control form-control-sm" required />
+            </div>
+            <div class="mb-2">
+                <label class="text-sm text-secondary mb-1">Last Name*</label>
+                <input type="text" name="lname" class="form-control form-control-sm" required />
+            </div>
+            <div class="mb-2">
+                <label class="text-sm text-secondary mb-1">Email Address*</label>
+                <input type="email" name="email" class="form-control form-control-sm" required>
+            </div>
+            <div class="mb-2">
+                <label class="text-sm text-secondary mb-1">How would you like us to notify you when your results are available?*</label>
+                <select class="form-control form-control-sm" name="notificationOption" v-model="form.notificationOption">
+                    <option value="">Select</option>
+                    <option value="email">Email Me</option>
+                    <option value="phone">Text Me (SMS)</option>
+                    <option value="none">Do not contact me, I will call in to check on my results.</option>
+                </select>
+            </div>
+            <div v-if="form.notificationOption === 'phone'" class="mb-2">
+                <label class="text-sm text-secondary mb-1">Phone Number*</label>
+                <input type="text" name="phoneNumber" class="form-control form-control-sm" required />
+            </div>
         </div>
         <div class="d-flex align-items-center mt-3">
             <button type="button" class="btn py-2 btn-grey border w-100 no-shadow" cancel>Cancel</button>
             <button class="btn py-2 btn-primary w-100 ms-3" submit>Submit</button>
         </div>
     </form>
-</div>
+</div>
+
+<script>
+    var createNewUserComponent = new Vue({
+        el:'#createNewUser',
+        data:{
+            form:{}
+        }
+    });
+</script>

+ 1 - 1
resources/views/app/my-account/admin/users/index.blade.php

@@ -3,7 +3,7 @@
     <div class="px-3">
         <div class="d-flex align-items-baseline border-bottom px-3 py-2 mb-2 m-neg-3 bg-light">
             <h2 class="font-size-16 text-secondary fw-bold m-0 me-3">Users</h2>
-            {{--@include('app.my-account.admin.users.forms.create')--}}
+            @include('app.my-account.admin.users.forms.create')
         </div>
         @include('app.my-account.admin.users.filters')
         @include('app.my-account.admin.users.partials.table', ['rows' => $users])

+ 12 - 1
resources/views/app/my-account/admin/users/sub/orders.blade.php

@@ -2,7 +2,13 @@
 
 @section('details')
     <div class="my-4">
-        <h4><b>Orders as Client</b></h4>
+        <div class="d-flex align-items-center justify-content-between">
+            <h4 class="m-0"><b>Orders as Client</b></h4>  
+            <div>
+                @include('app.my-account.admin.orders.forms.create-order')
+            </div>
+        </div>
+        
         <div class="table-responsive">
             <table class="table table-sm table-hover table-striped table-bordered mb-0">
                 <thead>
@@ -59,6 +65,11 @@
                             </td>
                         </tr>
                     @endforeach
+                    @if(!count($orders))
+                        <tr>
+                            <td colspan="5">No orders placed!</td>
+                        </tr>
+                    @endif
                 </tbody>
             </table>
         </div>

+ 20 - 0
resources/views/emails/templates/user-welcome-txt.blade.php

@@ -0,0 +1,20 @@
+Welcome, {{$user->name_display}}!
+
+Thank your for signing up.
+
+Please visit {{$appUrl}} to access your account.
+
+@if($temporaryPassword)
+Your temporary password is: {{ $temporaryPassword }}
+@endif
+
+If you have any questions, feel free to email our customer success team
+(We're lightning quick at replying.) We also offer live chat during business hours.
+
+Cheers,
+{{$emailFromName}}
+
+-----------
+
+
+©{{date('Y')}} {{ $stringMappingConfig['name'] }} -> {{$appUrl}}. All rights reserved.

+ 18 - 0
resources/views/emails/templates/user-welcome.blade.php

@@ -0,0 +1,18 @@
+@extends('emails.layout')
+@section('salutation')
+    Welcome, {{$user->displayName()}}!
+@endsection
+
+@section('content')
+    @if($temporaryPassword)
+        <p class="f-fallback" style="color: #000; font-size: 17px; padding: 0 15px; line-height: 30px; margin: .4em 0 0.1875em;">Thank you for signing up. Below is your temporary password to login.<br />
+        <span><b>{{ $temporaryPassword }}</b></span>
+    </p>
+    @else
+        <p class="f-fallback" style="color: #000; font-size: 17px; padding: 0 15px; line-height: 30px; margin: .4em 0 0.1875em;">Thank you for signing up. We’re thrilled to have you onboard. Please click the link below to complete the process.</p>
+    @endif
+    
+
+    @include('emails.call-to-action-button', ['link'=>$stringMappingConfig['clientUrl'] .'/my-account', 'label' => 'Access your account'])
+
+@endsection

+ 2 - 0
routes/web.php

@@ -48,6 +48,7 @@ Route::group(['middleware' => ['ensureUserLoggedIn']], function () {
         Route::prefix('/admin')->name('admin')->group(function () {
             Route::get('/dashboard', [AdminController::class, 'dashboard'])->name('.dashboard');
             Route::get('/users', [AdminController::class, 'users'])->name('.users');
+            Route::post('/create-new-user', [AdminController::class, 'createNewUser'])->name('.create-new-user');
             Route::prefix('/users/view/{user}')->name('.users.view')->group(function () {
                 Route::get('/dashboard', [AdminController::class, 'userDashboard'])->name('.dashboard');
                 Route::get('/orders', [AdminController::class, 'userOrders'])->name('.orders');
@@ -60,6 +61,7 @@ Route::group(['middleware' => ['ensureUserLoggedIn']], function () {
             });
             
             Route::get('/orders', [AdminController::class, 'orders'])->name('.orders');
+            Route::post('/create-order', [AdminController::class, 'orderCreate'])->name('.create-order');
             Route::prefix('/orders/view/{order}')->name('.orders.view')->group(function () {
                 Route::get('/dashboard', [AdminController::class, 'orderDashboard'])->name('.dashboard');
                 Route::get('/preview-invoice', [AdminController::class, 'orderPreviewInvoice'])->name('.preview-invoice');