Nền tảng Kiến thức - Hành trang tới Tương lai
Card image

Chương 11-Bài 11. Tạo đơn hàng và gởi mail xác nhận

Tác giả: Dương Nguyễn Phú Cường #103
Ngày đăng: Hồi xưa đó
Lượt xem: 416

Step 1: tạo route about

  • Hiệu chỉnh file routes/web.php
Route::get('/gio-hang', 'Frontend\FrontendController@cart')->name('frontend.cart');
Route::post('/dat-hang', 'Frontend\FrontendController@order')->name('frontend.order');
Route::get('/dat-hang/hoan-tat', 'Frontend\FrontendController@orderFinish')->name('frontend.orderFinish');

Step 2: viết code action

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Loai;
use App\Mau;
use App\Sanpham;
use App\Vanchuyen;
use App\Khachhang;
use App\Donhang;
use App\Thanhtoan;
use App\Chitietdonhang;
use Carbon\Carbon;
use DB;
use Mail;
use App\Mail\ContactMailer;
use App\Mail\OrderMailer;

...

/**
 * Action hiển thị giỏ hàng
 */
public function cart(Request $request)
{
    // Query danh sách hình thức vận chuyển
    $danhsachvanchuyen = Vanchuyen::all();

    // Query danh sách phương thức thanh toán
    $danhsachphuongthucthanhtoan = Thanhtoan::all();

    return view('frontend.pages.shopping-cart')
        ->with('danhsachvanchuyen', $danhsachvanchuyen)
        ->with('danhsachphuongthucthanhtoan', $danhsachphuongthucthanhtoan);
}

/**
 * Action Đặt hàng
 */
public function order(Request $request)
{
    // dd($request);
    // Data gởi mail
    $dataMail = [];
    try {
        // Tạo mới khách hàng
        $khachhang = new Khachhang();
        $khachhang->kh_taiKhoan = $request->khachhang['kh_taiKhoan'];
        $khachhang->kh_matKhau = bcrypt('123456');
        $khachhang->kh_hoTen = $request->khachhang['kh_hoTen'];
        $khachhang->kh_gioiTinh = $request->khachhang['kh_gioiTinh'];
        $khachhang->kh_email = $request->khachhang['kh_email'];
        $khachhang->kh_ngaySinh = $request->khachhang['kh_ngaySinh'];
        if(!empty($request->khachhang['kh_diaChi'])) {
            $khachhang->kh_diaChi = $request->khachhang['kh_diaChi'];
        }
        if(!empty($request->khachhang['kh_dienThoai'])) {
            $khachhang->kh_dienThoai = $request->khachhang['kh_dienThoai'];
        }
        $khachhang->kh_trangThai = 2; // Khả dụng
        $khachhang->save();
        $dataMail['khachhang'] = $khachhang->toArray();

        // Tạo mới đơn hàng
        $donhang = new Donhang();
        $donhang->kh_ma = $khachhang->kh_ma;
        $donhang->dh_thoiGianDatHang = Carbon::now();
        $donhang->dh_thoiGianNhanHang = $request->donhang['dh_thoiGianNhanHang'];
        $donhang->dh_nguoiNhan = $request->donhang['dh_nguoiNhan'];
        $donhang->dh_diaChi = $request->donhang['dh_diaChi'];
        $donhang->dh_dienThoai = $request->donhang['dh_dienThoai'];
        $donhang->dh_nguoiGui = $request->donhang['dh_nguoiGui'];
        $donhang->dh_loiChuc = $request->donhang['dh_loiChuc'];
        $donhang->dh_daThanhToan = 0; //Chưa thanh toán
        $donhang->nv_xuLy = 1; //Mặc định nhân viên đầu tiên
        $donhang->nv_giaoHang = 1; //Mặc định nhân viên đầu tiên
        $donhang->dh_trangThai = 1; //Nhận đơn
        $donhang->vc_ma = $request->donhang['vc_ma'];
        $donhang->tt_ma = $request->donhang['tt_ma'];
        $donhang->save();
        $dataMail['donhang'] = $donhang->toArray();

        // Lưu chi tiết đơn hàng
        foreach($request->giohang['items'] as $sp)
        {
            $chitietdonhang = new Chitietdonhang();
            $chitietdonhang->dh_ma = $donhang->dh_ma;
            $chitietdonhang->sp_ma = $sp['_id'];
            $chitietdonhang->m_ma = 1;
            $chitietdonhang->ctdh_soLuong = $sp['_quantity'];
            $chitietdonhang->ctdh_donGia = $sp['_price'];
            $chitietdonhang->save();
            $dataMail['donhang']['chitiet'][] = $chitietdonhang->toArray();
            $dataMail['donhang']['giohang'][] = $sp;
        }

        // Gởi mail khách hàng
        // dd($dataMail);
        Mail::to($khachhang->kh_email)
            ->send(new OrderMailer($dataMail));
    }
    catch(ValidationException $e) {
        return response()->json(array(
            'code'  => 500,
            'message' => $e,
            'redirectUrl' => route('frontend.home')
        ));
    } 
    catch(Exception $e) {
        throw $e;
    }

    return response()->json(array(
        'code'  => 200,
        'message' => 'Tạo đơn hàng thành công!',
        'redirectUrl' => route('frontend.orderFinish')
    ));
}

/**
 * Action Hoàn tất Đặt hàng
 */
public function orderFinish()
{
    return view('frontend.pages.order-finish');
}

...
Tạo view resources/views/frontend/pages/shopping-cart.blade.php
{{-- View này sẽ kế thừa giao diện từ `frontend.layouts.master` --}}
@extends('frontend.layouts.master')

{{-- Thay thế nội dung vào Placeholder `title` của view `frontend.layouts.master` --}}
@section('title')
Giỏ hàng Shop Hoa tươi - Sunshine
@endsection

{{-- Thay thế nội dung vào Placeholder `custom-css` của view `frontend.layouts.master` --}}
@section('custom-css')
@endsection

{{-- Thay thế nội dung vào Placeholder `main-content` của view `frontend.layouts.master` --}}
@section('main-content')

<!-- Hiển thị giỏ hàng -->
<ngcart-cart template-url="{{ asset('vendor/ngCart/template/ngCart/cart.html') }}"></ngcart-cart>

<!-- Thông tin khách hàng -->
<div class="container" ng-controller="orderController">
    <form name="orderForm" ng-submit="submitOrderForm()" novalidate>
        <div class="row">
            <div class="col-lg-6 col-md-6">
                <h2>Thông tin khách hàng</h2>
                <!-- Div Thông báo lỗi 
                Chỉ hiển thị khi các validate trong form `orderForm` không hợp lệ => orderForm.$invalid = true
                Sử dụng tiền chỉ lệnh ng-show="orderForm.$invalid"
                -->
                <div class="alert alert-danger" ng-show="orderForm.$invalid">
                    <ul>
                        <!-- Thông báo lỗi kh_email -->
                        <li><span class="error" ng-show="orderForm.kh_email.$error.required">Vui lòng nhập email</span></li>
                        <li><span class="error" ng-show="!orderForm.kh_email.$error.required && orderForm.kh_email.$error.pattern">Chỉ chấp nhập GMAIL, vui lòng kiểm tra lại</span></li>

                        <!-- Thông báo lỗi kh_taiKhoan -->
                        <li><span class="error" ng-show="orderForm.kh_taiKhoan.$error.required">Vui lòng nhập tên tài khoản</span></li>
                        <li><span class="error" ng-show="orderForm.kh_taiKhoan.$error.minlength">Tên tài khoản phải > 6 ký tự</span></li>
                        <li><span class="error" ng-show="orderForm.kh_taiKhoan.$error.maxlength">Tên tài khoản phải <= 50 ký tự</span> </li> <!-- Thông báo lỗi kh_hoTen -->
                        <li><span class="error" ng-show="orderForm.kh_hoTen.$error.required">Vui lòng nhập Họ tên</span></li>
                        <li><span class="error" ng-show="orderForm.kh_hoTen.$error.minlength">Họ tên phải > 6 ký tự</span></li>
                        <li><span class="error" ng-show="orderForm.kh_hoTen.$error.maxlength">Họ tên phải <= 100 ký tự</span> </li> <!-- Thông báo lỗi kh_gioiTinh -->
                        <li><span class="error" ng-show="orderForm.kh_gioiTinh.$error.required">Vui lòng chọn giới tính</span></li>

                        <!-- Thông báo lỗi kh_ngaySinh -->
                        <li><span class="error" ng-show="orderForm.kh_ngaySinh.$error.required">Vui lòng nhập Ngày sinh</span></li>

                        <!-- Thông báo lỗi kh_diaChi -->
                        <li><span class="error" ng-show="orderForm.kh_diaChi.$error.minlength">Địa chỉ phải > 6 ký tự</span></li>
                        <li><span class="error" ng-show="orderForm.kh_diaChi.$error.maxlength">Địa chỉ phải <= 250 ký tự</span> </li> <!-- Thông báo lỗi kh_dienThoai -->
                        <li><span class="error" ng-show="orderForm.kh_dienThoai.$error.minlength">Điện thoại phải > 6 ký tự</span></li>
                        <li><span class="error" ng-show="orderForm.kh_dienThoai.$error.maxlength">Điện thoại phải <= 11 ký tự</span> </li> </li> </div> <div class="form-group">
                                    <label for="kh_taiKhoan">Tài khoản:</label>
                                    <input type="text" class="form-control" id="kh_taiKhoan" name="kh_taiKhoan" ng-model="kh_taiKhoan" ng-minlength="6" ng-maxlength="50" ng-required=true>
                </div>
                <div class="form-group">
                    <label for="kh_hoTen">Họ tên:</label>
                    <input type="text" class="form-control" id="kh_hoTen" name="kh_hoTen" ng-model="kh_hoTen" ng-minlength="6" ng-maxlength="100" ng-required=true>
                </div>
                <div class="form-group">
                    <label for="kh_gioiTinh">Giới tính:</label>
                    <select name="kh_gioiTinh" id="kh_gioiTinh" class="form-control" ng-model="kh_gioiTinh" ng-required=true>
                        <option value="0">Nữ</option>
                        <option value="1">Nam</option>
                        <option value="2">Khác</option>
                    </select>
                </div>
                <div class="form-group">
                    <label for="kh_email">Email:</label>
                    <input type="email" class="form-control" id="kh_email" name="kh_email" ng-model="kh_email" ng-pattern="/^.+@gmail.com$/" ng-required=true>
                </div>
                <div class="form-group">
                    <label for="kh_ngaySinh">Ngày sinh:</label>
                    <input type="text" class="form-control" id="kh_ngaySinh" name="kh_ngaySinh" ng-model="kh_ngaySinh" ng-required=true>
                </div>
                <div class="form-group">
                    <label for="kh_diaChi">Địa chỉ:</label>
                    <input type="text" class="form-control" id="kh_diaChi" name="kh_diaChi" ng-model="kh_diaChi" ng-minlength="6" ng-maxlength="250">
                </div>
                <div class="form-group">
                    <label for="kh_dienThoai">Điện thoại:</label>
                    <input type="text" class="form-control" id="kh_dienThoai" name="kh_dienThoai" ng-model="kh_dienThoai" ng-minlength="6" ng-maxlength="11">
                </div>
            </div>

            <div class="col-lg-6 col-md-6">
                <h2>Thông tin Đặt hàng</h2>
                <!-- Div Thông báo lỗi 
                Chỉ hiển thị khi các validate trong form `orderForm` không hợp lệ => orderForm.$invalid = true
                Sử dụng tiền chỉ lệnh ng-show="orderForm.$invalid"
                -->
                <div class="alert alert-danger" ng-show="orderForm.$invalid">
                    <ul>
                        <!-- Thông báo lỗi dh_thoiGianDatHang -->
                        <li><span class="error" ng-show="orderForm.dh_thoiGianNhanHang.$error.required">Vui lòng nhập thời gian nhận hàng</span></li>

                        <!-- Thông báo lỗi dh_nguoiNhan -->
                        <li><span class="error" ng-show="orderForm.dh_nguoiNhan.$error.required">Vui lòng nhập tên người nhận</span></li>
                        <li><span class="error" ng-show="orderForm.dh_nguoiNhan.$error.minlength">Tên người nhận phải > 6 ký tự</span></li>
                        <li><span class="error" ng-show="orderForm.dh_nguoiNhan.$error.maxlength">Tên người nhận phải <= 100 ký tự</span> </li> <!-- Thông báo lỗi dh_diaChi -->
                        <li><span class="error" ng-show="orderForm.dh_diaChi.$error.required">Vui lòng nhập Địa chỉ</span></li>
                        <li><span class="error" ng-show="orderForm.dh_diaChi.$error.minlength">Địa chỉ phải > 6 ký tự</span></li>
                        <li><span class="error" ng-show="orderForm.dh_diaChi.$error.maxlength">Địa chỉ phải <= 250 ký tự</span> </li> <!-- Thông báo lỗi dh_dienThoai -->
                        <li><span class="error" ng-show="orderForm.dh_dienThoai.$error.required">Vui lòng nhập Điện thoại</span></li>
                        <li><span class="error" ng-show="orderForm.dh_dienThoai.$error.minlength">Điện thoại phải > 6 ký tự</span></li>
                        <li><span class="error" ng-show="orderForm.dh_dienThoai.$error.maxlength">Điện thoại phải <= 11 ký tự</span> </li> <!-- Thông báo lỗi dh_nguoiGui -->
                        <li><span class="error" ng-show="orderForm.dh_nguoiGui.$error.required">Vui lòng nhập Người gửi</span></li>
                        <li><span class="error" ng-show="orderForm.dh_nguoiGui.$error.minlength">Người gửi phải > 6 ký tự</span></li>
                        <li><span class="error" ng-show="orderForm.dh_nguoiGui.$error.maxlength">Người gửi phải <= 100 ký tự</span> </li> <!-- Thông báo lỗi dh_loiChuc -->
                        <li><span class="error" ng-show="orderForm.dh_loiChuc.$error.required">Vui lòng nhập Lời chúc</span></li>
                        <li><span class="error" ng-show="orderForm.dh_loiChuc.$error.minlength">Lời chúc phải > 6 ký tự</span></li>
                        <li><span class="error" ng-show="orderForm.dh_loiChuc.$error.maxlength">Lời chúc phải <= 500 ký tự</span> </li> <!-- Thông báo lỗi vc_ma -->
                        <li><span class="error" ng-show="orderForm.vc_ma.$error.required">Vui lòng chọn Hình thức vận chuyển</span></li>

                        <!-- Thông báo lỗi tt_ma -->
                        <li><span class="error" ng-show="orderForm.tt_ma.$error.required">Vui lòng chọn Phương thức thanh toán</span></li>
                        </li>
                </div>
                <div class="form-group">
                    <label for="dh_thoiGianNhanHang">Thời gian nhận hàng:</label>
                    <input type="text" class="form-control" id="dh_thoiGianNhanHang" name="dh_thoiGianNhanHang" ng-model="dh_thoiGianNhanHang" ng-required=true>
                </div>
                <div class="form-group">
                    <label for="dh_nguoiNhan">Người nhận:</label>
                    <input type="text" class="form-control" id="dh_nguoiNhan" name="dh_nguoiNhan" ng-model="dh_nguoiNhan" ng-minlength="6" ng-maxlength="100" ng-required=true>
                </div>
                <div class="form-group">
                    <label for="dh_diaChi">Địa chỉ:</label>
                    <input type="text" class="form-control" id="dh_diaChi" name="dh_diaChi" ng-model="dh_diaChi" ng-minlength="6" ng-maxlength="250" ng-required=true>
                </div>
                <div class="form-group">
                    <label for="dh_dienThoai">Điện thoại:</label>
                    <input type="text" class="form-control" id="dh_dienThoai" name="dh_dienThoai" ng-model="dh_dienThoai" ng-minlength="6" ng-maxlength="11" ng-required=true>
                </div>
                <div class="form-group">
                    <label for="dh_nguoiGui">Người gửi:</label>
                    <input type="text" class="form-control" id="dh_nguoiGui" name="dh_nguoiGui" ng-model="dh_nguoiGui" ng-minlength="6" ng-maxlength="100" ng-required=true>
                </div>
                <div class="form-group">
                    <label for="dh_loiChuc">Lời chúc:</label>
                    <textarea class="form-control" id="dh_loiChuc" name="dh_loiChuc" ng-model="dh_loiChuc" ng-minlength="6" ng-maxlength="500" ng-required=true></textarea>
                </div>
                <div class="form-group">
                    <label for="vc_ma">Hình thức vận chuyển:</label>
                    <select name="vc_ma" id="vc_ma" class="form-control" ng-model="vc_ma" ng-required=true>
                        @foreach($danhsachvanchuyen as $vc)
                        <option value="{{ $vc->vc_ma }}">{{ $vc->vc_ten }} ({{ $vc->vc_chiPhi }} đ)</option>
                        @endforeach
                    </select>
                </div>
                <div class="form-group">
                    <label for="tt_ma">Phương thức thanh toán:</label>
                    <select name="tt_ma" id="tt_ma" class="form-control" ng-model="tt_ma" ng-required=true>
                        @foreach($danhsachphuongthucthanhtoan as $tt)
                        <option value="{{ $tt->tt_ma }}">{{ $tt->tt_ten }}</option>
                        @endforeach
                    </select>
                </div>
            </div>
        </div>

        <!-- Div Thông báo validate hợp lệ 
        Chỉ hiển thị khi các validate trong form `orderForm` không hợp lệ => orderForm.$valid = true
        Sử dụng tiền chỉ lệnh ng-show="orderForm.$valid"
        -->
        <div class="alert alert-success" ng-show="orderForm.$valid">
            Thông tin hợp lệ, vui lòng bấm nút <b>"Thanh toán"</b> để hoàn tất ĐƠN HÀNG<br />
            Chúng tôi sẽ gởi mail đển quý khách. Xin chân thành cám ơn Quý Khách hàng đã tin tưởng sản phẩm của chúng tôi.
        </div>
        <!-- Nút submit form -->
        <button type="submit" class="flex-c-m stext-101 cl0 size-121 bg3 bor1 hov-btn3 p-lr-15 trans-04 pointer mb-4" ng-disabled="orderForm.$invalid && ngCart.getTotalItems() === 0">
            Thanh toán
        </button>
    </form>
</div>

@endsection

{{-- Thay thế nội dung vào Placeholder `custom-scripts` của view `frontend.layouts.master` --}}
@section('custom-scripts')
<script>
    // Khai báo controller `orderController`
    app.controller('orderController', function($scope, $http, ngCart) {
        $scope.ngCart = ngCart;

        // hàm submit form sau khi đã kiểm tra các ràng buộc (validate)
        $scope.submitOrderForm = function() {
            debugger;
            // kiểm tra các ràng buộc là hợp lệ, gởi AJAX đến action 
            if ($scope.orderForm.$valid) {
                // lấy data của Form
                var dataInputOrderForm_KhachHang = {
                    "kh_taiKhoan": $scope.orderForm.kh_taiKhoan.$viewValue,
                    "kh_hoTen": $scope.orderForm.kh_hoTen.$viewValue,
                    "kh_gioiTinh": $scope.orderForm.kh_gioiTinh.$viewValue,
                    "kh_email": $scope.orderForm.kh_email.$viewValue,
                    "kh_ngaySinh": $scope.orderForm.kh_ngaySinh.$viewValue,
                    "kh_diaChi": $scope.orderForm.kh_diaChi.$viewValue,
                    "kh_dienThoai": $scope.orderForm.kh_dienThoai.$viewValue,
                };

                var dataInputOrderForm_DatHang = {
                    "dh_thoiGianNhanHang": $scope.orderForm.dh_thoiGianNhanHang.$viewValue,
                    "dh_nguoiNhan": $scope.orderForm.dh_nguoiNhan.$viewValue,
                    "dh_diaChi": $scope.orderForm.dh_diaChi.$viewValue,
                    "dh_dienThoai": $scope.orderForm.dh_dienThoai.$viewValue,
                    "dh_nguoiGui": $scope.orderForm.dh_nguoiGui.$viewValue,
                    "dh_loiChuc": $scope.orderForm.dh_loiChuc.$viewValue,
                    "vc_ma": $scope.orderForm.vc_ma.$viewValue,
                    "tt_ma": $scope.orderForm.tt_ma.$viewValue,
                };

                var dataCart = ngCart.getCart();

                var dataInputOrderForm = {
                    "khachhang": dataInputOrderForm_KhachHang,
                    "donhang": dataInputOrderForm_DatHang,
                    "giohang": dataCart,
                    "_token": "{{ csrf_token() }}",
                };

                // sử dụng service $http của AngularJS để gởi request POST đến route `frontend.order`
                $http({
                    url: "{{ route('frontend.order') }}",
                    method: "POST",
                    data: JSON.stringify(dataInputOrderForm)
                }).then(function successCallback(response) {
                    // Clear giỏ hàng ngCart
                    //$scope.ngCart.empty();

                    // Gởi mail thành công, thông báo cho khách hàng biết
                    swal('Đơn hàng hoàn tất!', 'Xin cám ơn Quý khách!', 'success');

                    // Chuyển sang trang Hoàn tất đặt hàng
                    if (response.data.redirectUrl) {
                        location.href = response.data.redirectUrl;
                    }
                }, function errorCallback(response) {
                    // Gởi mail không thành công, thông báo lỗi cho khách hàng biết
                    swal('Có lỗi trong quá trình thực hiện Đơn hàng!', 'Vui lòng thử lại sau vài phút.', 'error');
                    console.log(response);
                });
            }
        };
    });
</script>
@endsection
Tạo view resources/views/frontend/pages/order-finish.blade.php
{{-- View này sẽ kế thừa giao diện từ `frontend.layouts.master` --}}
@extends('frontend.layouts.master')

{{-- Thay thế nội dung vào Placeholder `title` của view `frontend.layouts.master` --}}
@section('title')
Giới thiệu Shop Hoa tươi - Sunshine
@endsection

{{-- Thay thế nội dung vào Placeholder `custom-css` của view `frontend.layouts.master` --}}
@section('custom-css')
@endsection

{{-- Thay thế nội dung vào Placeholder `main-content` của view `frontend.layouts.master` --}}
@section('main-content')
<!-- Title page -->
<section class="bg-img1 txt-center p-lr-15 p-tb-92" style="background-image: url('{{ asset('themes/cozastore/images/bg-01.jpg') }}');">
    <h2 class="ltext-105 cl0 txt-center">
        Đặt hàng hoàn tất
    </h2>
</section>


<!-- Content page -->
<section class="bg0 p-t-75 p-b-120">
    <div class="container">
        <div class="row p-b-148">
            <div class="col-md-7 col-lg-8">
                <div class="p-t-7 p-r-85 p-r-15-lg p-r-0-md">
                    <h3 class="mtext-111 cl2 p-b-16">
                        Đặt hàng hoàn tất
                    </h3>

                    <p class="stext-113 cl6 p-b-26">
                        Chúng tôi đã gởi email xác nhận đơn hàng cho Quý khách. Quý khách vui vòng kiểm tra hộp thư.
                        Xin cám ơn Quý khách đã tin tưởng sản phẩm của chúng tôi.
                    </p>

                    <p class="stext-113 cl6 p-b-26">
                        Nếu cần hỗ trợ, vui lòng gọi đến đường dây nóng của chúng tôi để được hỗ trợ khi cần thiết:<br />
                        TEL: 0915-659-223
                    </p>
                </div>
            </div>

            <div class="col-11 col-md-5 col-lg-4 m-lr-auto">
                <div class="how-bor1 ">
                    <div class="hov-img0">
                        <img src="{{ asset('themes/cozastore/images/about-01.jpg') }}" alt="IMG">
                    </div>
                </div>
            </div>
        </div>
    </div>
</section>

@endsection

{{-- Thay thế nội dung vào Placeholder `custom-scripts` của view `frontend.layouts.master` --}}
@section('custom-scripts')
@endsection

Step 3: tạo mail OrderMailer

Chạy câu lệnh:

php artisan make:mail OrderMailer
Nội dung file
<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;

class OrderMailer extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Tạo biến chứa dữ liệu dùng để render email template
     */
    public $data;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct($data)
    {
        $this->data = $data;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        $dh_ma = $this->data['donhang']['dh_ma'];
        return $this->from(env('MAIL_FROM_ADDRESS', 'hotro.nentangtoituonglai@gmail.com'), env('MAIL_FROM_NAME', 'HoTro'))
            ->subject("Đơn hàng [$dh_ma] hoàn tất")
            ->view('emails.order-email')
            ->with('data', $this->data);
    }
}

Tạo template mail resources/views/emails/order-email.blade.php:

<table style="width: 100%; border-spacing: 0px">
    <tr>
        <td style="border-top: 1px solid black;border-bottom: 1px solid black;border-right: 1px solid black;border-left: 1px solid black; width: 153px; padding: 5px;">
            <img src="https://nentang.vn/wp-content/uploads/2018/08/logo-nentang.jpg" style="width: 153px; height: 153px;" />
        </td>
        <td style="border-top: 1px solid black;border-bottom: 1px solid black;border-right: 1px solid black; text-align: center; vertical-align: middle; padding: 5px;" colspan="3">
            <h1 style="color: red;">Shop hoa tươi Sunshine</h1>
        </td>
    </tr>
    <tr>
        <td colspan="4" style="border-bottom: 1px solid black;border-right: 1px solid black;border-left: 1px solid black; padding: 5px;">
            Thông tin đơn hàng [{{ $data['donhang']['dh_ma'] }}]
        </td>
    </tr>
    <tr>
        <th style="border-bottom: 1px solid black;border-right: 1px solid black;border-left: 1px solid black;text-align: right; padding: 5px;">Tài khoản
            khách hàng:</th>
        <td style="border-bottom: 1px solid black;border-right: 1px solid black; padding: 5px;">{{ $data['khachhang']['kh_taiKhoan'] }}</td>

        <th style="border-bottom: 1px solid black;border-right: 1px solid black;border-left: 1px solid black;text-align: right; padding: 5px;">Thời gian đặt hàng:</th>
        <td style="border-bottom: 1px solid black;border-right: 1px solid black; padding: 5px;">{{ $data['donhang']['dh_thoiGianDatHang'] }}</td>
    </tr>
    <tr>
        <th style="border-bottom: 1px solid black;border-right: 1px solid black;border-left: 1px solid black;text-align: right; padding: 5px;">Email
            khách hàng:</th>
        <td style="border-bottom: 1px solid black;border-right: 1px solid black; padding: 5px;">{{ $data['khachhang']['kh_email'] }}</td>

        <th style="border-bottom: 1px solid black;border-right: 1px solid black;border-left: 1px solid black;text-align: right; padding: 5px;">Người nhận:</th>
        <td style="border-bottom: 1px solid black;border-right: 1px solid black; padding: 5px;">{{ $data['donhang']['dh_nguoiNhan'] }}</td>
    </tr>
    <tr>
        <th style="border-bottom: 1px solid black;border-right: 1px solid black;border-left: 1px solid black;text-align: right; padding: 5px;">Địa chỉ
            khách hàng:</th>
        <td style="border-bottom: 1px solid black;border-right: 1px solid black; padding: 5px;">{{ $data['khachhang']['kh_diaChi'] }}</td>

        <th style="border-bottom: 1px solid black;border-right: 1px solid black;border-left: 1px solid black;text-align: right; padding: 5px;">Địa chỉ người nhận:</th>
        <td style="border-bottom: 1px solid black;border-right: 1px solid black; padding: 5px;">{{ $data['donhang']['dh_diaChi'] }}</td>
    </tr>
    <tr>
        <th style="border-bottom: 1px solid black;border-right: 1px solid black;border-left: 1px solid black;text-align: right; padding: 5px;">Số điện thoại
            khách hàng:</th>
        <td style="border-bottom: 1px solid black;border-right: 1px solid black; padding: 5px;">{{ $data['khachhang']['kh_dienThoai'] }}</td>

        <th style="border-bottom: 1px solid black;border-right: 1px solid black;border-left: 1px solid black;text-align: right; padding: 5px;">Lời chúc:</th>
        <td style="border-bottom: 1px solid black;border-right: 1px solid black; padding: 5px;">{{ $data['donhang']['dh_loiChuc'] }}</td>
    </tr>
    <tr>
        <td colspan="4">
            <ul>
                @foreach($data['donhang']['giohang'] as $item)
                <li>{{ $item['_name'] }}: {{ $item['_quantity'] }} x {{ $item['_price'] }}</li>
                @endforeach
            </ul>
        </td>
    </tr>
</table>
   

Chương trình học


  1. Bức tranh Tổng thể về Lập trình WEB
  2. Giới thiệu, cài đặt, cấu hình môi trường lập trình 9
    1. Cài đặt web server XAMPP #84
    2. Cài đặt công cụ truy vấn database HeidiSQL #85
    3. Cài đặt Composer để quản lý các gói thư viện trong PHP #86
    4. Cài đặt trình soạn thảo code Visual Studio Code IDE #64
    5. Tạo tên miền ảo trên máy cục bộ (virtual host on localhost) bằng XAMPP #107
    6. Cài đặt nền tảng quản lý Source Code sử dụng GIT #1030
    7. Cài đặt công cụ quản lý Source Code TortoiseGit #1045
    8. Cài đặt chế độ Debug PHP với Visual Studio Code #8066
    9. Tạo chứng chỉ SSL trên Localhost #10399
  3. Tập làm quen với quản lý source code bằng GitHub 3
    1. GitHub là gì? #79
    2. Tạo tài khoản, tạo kho dữ liệu (repository), clone source, commit/push và pull source với GitHub #2303
    3. Cách đóng gói phiên bản (Alpha, Beta, Release) bằng Tag trong GitHub #9415
  4. Cài đặt framework Laravel 1
    1. Cài đặt Framework Laravel #66
  5. Tìm hiểu mô hình kiến trúc MVC vận hành trong framework Laravel 4
    1. Cấu trúc thư mục trong Framework Laravel #9211
    2. Kiến trúc MVC là gì? #65
    3. Mô hình kiến trúc MVC vận hành trong Framework Laravel #67
    4. Thực hiện code theo mô hình kiến trúc MVC vận hành trong Framework Laravel #2341
  6. Sử dụng Template Engine để trình diễn nội dung trong các VIEW 3
    1. Template Engine là gì? #2356
    2. Blade Template Engine trong Laravel #2357
    3. Bài tập View - tạo trang Danh sách nhân viên sử dụng Blade Template #2381
  7. Dự án thực tế mẫu - Trang web bán hàng trực tuyến - Thiết kế CSDL 7
    1. Phân tích các yêu cầu, nghiệp vụ của khách hàng #68
    2. Mô hình thiết kế CSDL mẫu Sunshine #69
    3. Khởi tạo database sunshine, thiết lập kết nối CSDL trong Laravel #1143
    4. Tạo cấu trúc table bằng tính năng MIGRATION trong Laravel - Danh mục phẳng #70
    5. Tạo cấu trúc table bằng tính năng MIGRATION trong Laravel - Danh mục có liên kết khóa ngoại #1157
    6. Tạo dữ liệu ban đầu cho CSDL bằng tính năng SEED trong Laravel - Danh mục phẳng #71
    7. Tạo dữ liệu ban đầu cho CSDL bằng tính năng SEED trong Laravel - Danh mục có liên kết khóa ngoại #7851
  8. Dự án thực tế mẫu - Trang web bán hàng trực tuyến - Ánh xạ CSDL và Laravel 3
    1. Tạo lớp (class) ánh xạ CSDL bằng tính năng MODEL trong Laravel - Danh mục Phẳng - Loại sản phẩm #1165
    2. Tạo lớp (class) ánh xạ CSDL bằng tính năng MODEL trong Laravel - Danh mục phẳng - Sản phẩm #1166
    3. Tạo mối quan hệ giữa các lớp (class) MODEL trong Laravel #1174
  9. Dự án thực tế mẫu - Trang web bán hàng trực tuyến - Thiết kế Backend 20
    1. Thiết kế bố cục (layouts) cho giao diện Backend #72
    2. Xây dựng chức năng CRUD (Thêm, Sửa, Xóa, Xem) danh mục phẳng - Loại sản phẩm (index) #135
    3. Xây dựng chức năng CRUD (Thêm, Sửa, Xóa, Xem) danh mục phẳng - Loại sản phẩm (create) #137
    4. Xây dựng chức năng CRUD (Thêm, Sửa, Xóa, Xem) danh mục phẳng - Loại sản phẩm (edit) #138
    5. Xây dựng chức năng CRUD (Thêm, Sửa, Xóa, Xem) danh mục phẳng - Loại sản phẩm (delete) #139
    6. Xây dựng danh mục Sản phẩm có chức năng upload hình ảnh - Index #75
    7. Lưu đồ Upload file từ Client lên Server #2229
    8. Xây dựng danh mục Sản phẩm có chức năng upload hình ảnh - Create #108
    9. Xây dựng danh mục Sản phẩm có chức năng upload hình ảnh - Edit #87
    10. Xây dựng danh mục Sản phẩm có chức năng upload hình ảnh - Delete #88
    11. Xây dựng danh mục Sản phẩm có chức năng upload nhiều Hình ảnh cùng lúc #9259
    12. Xây dựng danh mục Sản phẩm có chức năng upload hình ảnh - Bổ sung menu vào sidebar #104
    13. Xây dựng chức năng xuất biểu mẫu và In ấn trực tiếp trên web #78
    14. Xây dựng chức năng xuất Excel #76
    15. Xây dựng chức năng xuất PDF #77
    16. Tạo chức năng Đăng nhập #1870
    17. Lưu đồ Kiểm tra ràng buộc dữ liệu (Validation) #2205
    18. Kiểm tra ràng buộc dữ liệu (Validation) phía Client #2206
    19. Kiểm tra ràng buộc dữ liệu (Validation) phía Server #2207
    20. Bài tập tổng hợp - Tạo các chức năng Backend cho trang web đọc Truyện Tranh và Tiểu Thuyết Online sử dụng Laravel framework #9312
  10. AngularJS 7
    1. AngularJS là gì? Cài đặt AngularJS và cú pháp sử dụng AngularJS #95
    2. Cách mô hình kiến trúc MVC vận hành trong AngularJS #96
    3. Cách sử dụng AngularJS Controller, Scope #98
    4. Cách sử dụng AngularJS Directive #97
    5. Cách sử dụng AngularJS Event #100
    6. Cách sử dụng AngularJS Filter #99
    7. Cách sử dụng AngularJS Validation #101
  11. Dự án thực tế mẫu - Trang web bán hàng trực tuyến - Thiết kế Frontend sử dụng AngularJS 11
    1. Thiết kế bố cục (layouts) cho giao diện Frontend #80
    2. Tích hợp AngularJS vào framework Laravel #102
    3. Tạo giao diện trang chủ (index) #81
    4. Tạo giao diện trang Giới thiệu (about) #109
    5. Tạo giao diện trang Liên hệ (contact) #114
    6. Tạo trang danh sách Sản phẩm (product) #110
    7. Tạo nút Thêm vào giỏ hàng cho từng sản phẩm (add-to-cart) #112
    8. Tạo trang Chi tiết Sản phẩm (product-detail) #111
    9. Tạo giỏ hàng (cart sidebar) #82
    10. Tạo trang thanh toán (checkout) #83
    11. Tạo đơn hàng và gởi mail xác nhận #103
  12. Bonus 9
    1. Đa ngôn ngữ trong Laravel #115
    2. Tạo báo cáo với biểu đồ ChartJS #116
    3. Tạo khung chọn Ngày tháng cho dự án #2431
    4. Tạo các trang thông báo lỗi tương ứng STATUS CODE #117
    5. Kiểm tra ứng dụng với tunnel ảo NGROK #2418
    6. Phân trang trong Laravel #2436
    7. Bổ sung khung xem Hình ảnh trước khi upload (preview image upload) #2439
    8. Tạo API trong Laravel và sử dụng AngularJS để hiển thị giao diện #9385
    9. Cách tự động sinh Ảnh nhiều kích cỡ (Automatic resize image) khi upload file Ảnh #9970
  13. Danh sách Đồ án xây dựng trang web sử dụng LARAVEL 2
    1. Đăng ký Đồ án Laravel #1188
    2. Hướng dẫn Nộp Đồ án Laravel #9417
  14. Tài liệu tham khảo 3
    1. Kho sách, nguồn tài liệu tham khảo #1313
    2. SourceCode Dự án mẫu #113
    3. Xây dựng chức năng Tìm kiếm theo nhiều tiêu chí bằng Model Eloquent #9426
  15. Thực hiện Đồ án 1
    1. Lộ trình Thực hiện đồ án Web Laravel #7883
Các bài học

Chương trình học

Bao gồm Module, Chương, Bài học, Bài tập, Kiểm tra...

Chương trình học


  1. Bức tranh Tổng thể về Lập trình WEB
  2. Giới thiệu, cài đặt, cấu hình môi trường lập trình 9
    1. Cài đặt web server XAMPP #84
    2. Cài đặt công cụ truy vấn database HeidiSQL #85
    3. Cài đặt Composer để quản lý các gói thư viện trong PHP #86
    4. Cài đặt trình soạn thảo code Visual Studio Code IDE #64
    5. Tạo tên miền ảo trên máy cục bộ (virtual host on localhost) bằng XAMPP #107
    6. Cài đặt nền tảng quản lý Source Code sử dụng GIT #1030
    7. Cài đặt công cụ quản lý Source Code TortoiseGit #1045
    8. Cài đặt chế độ Debug PHP với Visual Studio Code #8066
    9. Tạo chứng chỉ SSL trên Localhost #10399
  3. Tập làm quen với quản lý source code bằng GitHub 3
    1. GitHub là gì? #79
    2. Tạo tài khoản, tạo kho dữ liệu (repository), clone source, commit/push và pull source với GitHub #2303
    3. Cách đóng gói phiên bản (Alpha, Beta, Release) bằng Tag trong GitHub #9415
  4. Cài đặt framework Laravel 1
    1. Cài đặt Framework Laravel #66
  5. Tìm hiểu mô hình kiến trúc MVC vận hành trong framework Laravel 4
    1. Cấu trúc thư mục trong Framework Laravel #9211
    2. Kiến trúc MVC là gì? #65
    3. Mô hình kiến trúc MVC vận hành trong Framework Laravel #67
    4. Thực hiện code theo mô hình kiến trúc MVC vận hành trong Framework Laravel #2341
  6. Sử dụng Template Engine để trình diễn nội dung trong các VIEW 3
    1. Template Engine là gì? #2356
    2. Blade Template Engine trong Laravel #2357
    3. Bài tập View - tạo trang Danh sách nhân viên sử dụng Blade Template #2381
  7. Dự án thực tế mẫu - Trang web bán hàng trực tuyến - Thiết kế CSDL 7
    1. Phân tích các yêu cầu, nghiệp vụ của khách hàng #68
    2. Mô hình thiết kế CSDL mẫu Sunshine #69
    3. Khởi tạo database sunshine, thiết lập kết nối CSDL trong Laravel #1143
    4. Tạo cấu trúc table bằng tính năng MIGRATION trong Laravel - Danh mục phẳng #70
    5. Tạo cấu trúc table bằng tính năng MIGRATION trong Laravel - Danh mục có liên kết khóa ngoại #1157
    6. Tạo dữ liệu ban đầu cho CSDL bằng tính năng SEED trong Laravel - Danh mục phẳng #71
    7. Tạo dữ liệu ban đầu cho CSDL bằng tính năng SEED trong Laravel - Danh mục có liên kết khóa ngoại #7851
  8. Dự án thực tế mẫu - Trang web bán hàng trực tuyến - Ánh xạ CSDL và Laravel 3
    1. Tạo lớp (class) ánh xạ CSDL bằng tính năng MODEL trong Laravel - Danh mục Phẳng - Loại sản phẩm #1165
    2. Tạo lớp (class) ánh xạ CSDL bằng tính năng MODEL trong Laravel - Danh mục phẳng - Sản phẩm #1166
    3. Tạo mối quan hệ giữa các lớp (class) MODEL trong Laravel #1174
  9. Dự án thực tế mẫu - Trang web bán hàng trực tuyến - Thiết kế Backend 20
    1. Thiết kế bố cục (layouts) cho giao diện Backend #72
    2. Xây dựng chức năng CRUD (Thêm, Sửa, Xóa, Xem) danh mục phẳng - Loại sản phẩm (index) #135
    3. Xây dựng chức năng CRUD (Thêm, Sửa, Xóa, Xem) danh mục phẳng - Loại sản phẩm (create) #137
    4. Xây dựng chức năng CRUD (Thêm, Sửa, Xóa, Xem) danh mục phẳng - Loại sản phẩm (edit) #138
    5. Xây dựng chức năng CRUD (Thêm, Sửa, Xóa, Xem) danh mục phẳng - Loại sản phẩm (delete) #139
    6. Xây dựng danh mục Sản phẩm có chức năng upload hình ảnh - Index #75
    7. Lưu đồ Upload file từ Client lên Server #2229
    8. Xây dựng danh mục Sản phẩm có chức năng upload hình ảnh - Create #108
    9. Xây dựng danh mục Sản phẩm có chức năng upload hình ảnh - Edit #87
    10. Xây dựng danh mục Sản phẩm có chức năng upload hình ảnh - Delete #88
    11. Xây dựng danh mục Sản phẩm có chức năng upload nhiều Hình ảnh cùng lúc #9259
    12. Xây dựng danh mục Sản phẩm có chức năng upload hình ảnh - Bổ sung menu vào sidebar #104
    13. Xây dựng chức năng xuất biểu mẫu và In ấn trực tiếp trên web #78
    14. Xây dựng chức năng xuất Excel #76
    15. Xây dựng chức năng xuất PDF #77
    16. Tạo chức năng Đăng nhập #1870
    17. Lưu đồ Kiểm tra ràng buộc dữ liệu (Validation) #2205
    18. Kiểm tra ràng buộc dữ liệu (Validation) phía Client #2206
    19. Kiểm tra ràng buộc dữ liệu (Validation) phía Server #2207
    20. Bài tập tổng hợp - Tạo các chức năng Backend cho trang web đọc Truyện Tranh và Tiểu Thuyết Online sử dụng Laravel framework #9312
  10. AngularJS 7
    1. AngularJS là gì? Cài đặt AngularJS và cú pháp sử dụng AngularJS #95
    2. Cách mô hình kiến trúc MVC vận hành trong AngularJS #96
    3. Cách sử dụng AngularJS Controller, Scope #98
    4. Cách sử dụng AngularJS Directive #97
    5. Cách sử dụng AngularJS Event #100
    6. Cách sử dụng AngularJS Filter #99
    7. Cách sử dụng AngularJS Validation #101
  11. Dự án thực tế mẫu - Trang web bán hàng trực tuyến - Thiết kế Frontend sử dụng AngularJS 11
    1. Thiết kế bố cục (layouts) cho giao diện Frontend #80
    2. Tích hợp AngularJS vào framework Laravel #102
    3. Tạo giao diện trang chủ (index) #81
    4. Tạo giao diện trang Giới thiệu (about) #109
    5. Tạo giao diện trang Liên hệ (contact) #114
    6. Tạo trang danh sách Sản phẩm (product) #110
    7. Tạo nút Thêm vào giỏ hàng cho từng sản phẩm (add-to-cart) #112
    8. Tạo trang Chi tiết Sản phẩm (product-detail) #111
    9. Tạo giỏ hàng (cart sidebar) #82
    10. Tạo trang thanh toán (checkout) #83
    11. Tạo đơn hàng và gởi mail xác nhận #103
  12. Bonus 9
    1. Đa ngôn ngữ trong Laravel #115
    2. Tạo báo cáo với biểu đồ ChartJS #116
    3. Tạo khung chọn Ngày tháng cho dự án #2431
    4. Tạo các trang thông báo lỗi tương ứng STATUS CODE #117
    5. Kiểm tra ứng dụng với tunnel ảo NGROK #2418
    6. Phân trang trong Laravel #2436
    7. Bổ sung khung xem Hình ảnh trước khi upload (preview image upload) #2439
    8. Tạo API trong Laravel và sử dụng AngularJS để hiển thị giao diện #9385
    9. Cách tự động sinh Ảnh nhiều kích cỡ (Automatic resize image) khi upload file Ảnh #9970
  13. Danh sách Đồ án xây dựng trang web sử dụng LARAVEL 2
    1. Đăng ký Đồ án Laravel #1188
    2. Hướng dẫn Nộp Đồ án Laravel #9417
  14. Tài liệu tham khảo 3
    1. Kho sách, nguồn tài liệu tham khảo #1313
    2. SourceCode Dự án mẫu #113
    3. Xây dựng chức năng Tìm kiếm theo nhiều tiêu chí bằng Model Eloquent #9426
  15. Thực hiện Đồ án 1
    1. Lộ trình Thực hiện đồ án Web Laravel #7883

Bài học trước Bài học tiếp theo