<repo_name>Laravel-all/PizzaTaskApi<file_sep>/app/Services/Parameter.php
<?php
namespace App\Services;

use App\Parameter as ParameterModel;


class Parameter
{
    public function getAll()
    {
       $parameters = ParameterModel::all();
       return $parameters;
    }
    
    public function get(string $parameter)
    {
       return ParameterModel::where('name', $parameter)->get()->first();
    }
}<file_sep>/app/Http/Controllers/SizeController.php
<?php

namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Services\Size as SizeService;

class SizeController extends Controller
{
    public function __construct(SizeService $sizeService)
    {
        $this->_sizeService  = $sizeService;
    }

    public function index()
    {
        return $this->_sizeService->getAll();
    }
}
<file_sep>/app/Http/Controllers/Auth/LoginController.php
<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller
{
    /*
    |-------------------------------------------------------------------
    | Login Controller
    |-------------------------------------------------------------------
    |
    | This controller handles authenticating users for the application and
    | redirecting them to your home screen. The controller uses a trait
    | to conveniently provide its functionality to your applications.
    |
    */
    /*
    public function __construct(Guard $auth)
	{
		$this->auth = $auth;

		$this->middleware('guest', ['except' => 'getLogout']);
    }
    */
    public function login(Request $request)
    {
        //$this->validateLogin($request);
        
        
        $credentials = $request->only('email', 'password');

        if (Auth::attempt($credentials)) {
            $user = Auth::user();  // Get the currently authenticated user...
            $user->generateToken();

            return response()->json([
                'data' => $user->toArray(),
            ]);
        }
        else{ 
            //return $this->sendError('Unauthorised.', ['error'=>'Unauthorised']);
            return response()->json([
                'error' => 'Unauthorized',
            ]);
        } 
        

    }

    public function logout(Request $request)
    {
        $user = Auth::guard('api')->user();

        if ($user) {
            $user->api_token = null;
            $user->save();
        }

        return response()->json(['data' => 'User logged out.'], 200);
    }
}




/*
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class LoginController extends Controller
{

    public function authenticate(Request $request)
    {
        $credentials = $request->only('user', 'password');

        if (Auth::attempt($credentials)) {
            // Authentication passed...
            return redirect()->intended('dashboard');
        }
    }
}
*/<file_sep>/app/Services/Pizza.php
<?php
namespace App\Services;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use App\Pizza as PizzaModel;


class Pizza
{
    public function getAll()
    {
       $pizzas = PizzaModel::all();
       return $pizzas;
    }

    public function create(Request $request)
    {
       $pizza = new PizzaModel;
       $pizza->name = $request->name;
       $pizza->price = $request->price;
       $pizza->save();
    }

    public function get($id){
        return PizzaModel::where('id', $id)->get();
    }

    public function update($request)
    {
        $pizza = PizzaModel::findOrFail($request->id);
        $pizza->name = $request->name;
        $pizza->save();
        return $pizza;
    }

    public function delete($id)
    {
        $pizza = PizzaModel::destroy($id);
        return $pizza;
    }

    /**
     * Get a validator for a order.
     *
     * @param  array $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    public function validator(array $data)
    {
        $rules=[
            'name' => 'required|string|max:100',
            'price' => 'required|max:11|regex:/^-?[0-9]+(?:\.[0-9]{1,2})?$/'
        ];

        $messages=[
            'name' => 'Name is required!',
            'price' => 'Price is required!'
        ];

        return Validator::make($data, $rules, $messages);
    }
}<file_sep>/app/Services/Size.php
<?php
namespace App\Services;

use App\Size as SizeModel;

class Size
{
    public function getAll()
    {
       $sizes = SizeModel::all();
       return $sizes;
    }
}<file_sep>/database/migrations/2020_05_23_202019_create_table_order_detail.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateTableOrderDetail extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('table_order_detail', function (Blueprint $table) {
            $table->integer('order_id');
            $table->integer('pizza_id');
            $table->integer('size_id');
            $table->integer('quantity');
            $table->decimal('single_price');
            $table->decimal('total_price');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('table_order_detail');
    }
}
<file_sep>/app/Order.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Order extends Model
{
    protected $fillable = [
        'datetime', 'ship_price', 'total'
    ];

    function orderContact() 
    { 
        return $this->hasOne('App\OrderContact'); 
    }

    function orderDetails() { 
        return $this->hasMany('App\OrderDetail'); 
    }
}
<file_sep>/database/seeds/PizzaTableSeeder.php
<?php

use Illuminate\Database\Seeder;
use App\Pizza;

class PizzaTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        // Let's truncate our existing records to start from scratch.
        Pizza::truncate();

        //$faker = \Faker\Factory::create();

        // And now, let's create a few articles in our database:
        
        Pizza::create([
            'name' => 'Pepperoni',
            'price' => 17,
        ]);

        Pizza::create([
            'name' => 'Chesse',
            'price' => 15,
        ]);

        Pizza::create([
            'name' => 'Tunna',
            'price' => 21,
        ]);

        Pizza::create([
            'name' => 'Chicken',
            'price' => 20,
        ]);

        Pizza::create([
            'name' => 'Four Cheese',
            'price' => 23,
        ]);

        Pizza::create([
            'name' => 'Fugazzeta',
            'price' => 22,
        ]);

        Pizza::create([
            'name' => 'Veggie',
            'price' => 20,
        ]);

        Pizza::create([
            'name' =>  'Neapolitan',
            'price' => 18,
        ]);

    }
}
<file_sep>/app/Services/Order.php
<?php
namespace App\Services;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use App\Order  as OrderModel;
use App\OrderDetail  as OrderDetailModel;
use App\OrderContact as OrderContactModel;


use App\Services\Pizza as PizzaService;
use App\Services\Size as SizeService;
use App\Services\Parameter as ParameterService;

class Order
{
    function __construct(PizzaService $pizzaService, SizeService $sizeService, ParameterService $parameterService) {
        $this->pizza = $pizzaService->getAll();
        $this->size = $sizeService->getAll();
        $this->deliveryCost = (double)$parameterService->get("deliveryCost")->value;
    }

    /**
     * Get a validator for a order.
     *
     * @param  array $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    public function validator(array $data)
    {
        $rules=[
            'order.orderContact.fullName' => 'required|string|max:100',
            'order.orderContact.phoneNumber' => 'required|string|max:50',
            'order.orderContact.fullAddress' => 'required|string|max:100',
            'order.orderContact.zipCode' => 'required|string|max:50',
            'order.orderDetail.*.idPizza' => 'required|numeric|gt:0',
            'order.orderDetail.*.idSize' => 'required|numeric|gt:0',
            'order.orderDetail.*.quantity' => 'required|numeric|gt:0'
        ];

        $messages=[
            'order.orderContact.fullName' => 'Name is required!',
            'order.orderContact.phoneNumber' => 'Name is required!',
            'order.orderContact.fullAddress' => 'Address is required!',
            'order.orderContact.zipCode' => 'Address is required!',
            'order.orderDetail.*.idPizza' => 'Pizza is required!',
            'order.orderDetail.*.idSize' => 'Size is required!',
            'order.orderDetail.*.quantity' => 'Quantity is required!',
        ];

        return Validator::make($data, $rules, $messages);
    }

    public function getAll()
    {
        return OrderModel::with('orderContact','orderDetails')
            ->orderBy('datetime', 'desc')
            ->take(50)
            ->get();
    }

    public function get($id)
    {
        return OrderModel::with('orderContact','orderDetails')
        ->where('id', $id)
        ->get();
    }

    /**
     * Create a new contact instance after a valid form.
     *
     * @param  array $data
     * @return ContactModel
     */
    public function create(array $request)
    {
        try{
            DB::beginTransaction();
            
            $order = new OrderModel;
            $order->datetime = date("Y-m-d-H:i:s");
            $order->ship_price = $this->deliveryCost;
            $order->total = $this->calculateTotalPriceOrder($request);
            $order->save();

            
            for ($i = 0; $i < count($request["order"]["orderDetail"]); $i++) 
            {
                    $itemElement = new OrderDetailModel;
                    $itemElement->order_id= $order->id;
                    $itemElement->pizza_id=$request["order"]["orderDetail"][$i]["idPizza"];
                    $itemElement->size_id=$request["order"]["orderDetail"][$i]["idSize"];
                    $itemElement->quantity=$request["order"]["orderDetail"][$i]["quantity"];

                    $price=$this->calculatePrice($itemElement->pizza_id, $itemElement->size_id);
                    $totalPrice=$price * $itemElement->quantity;

                    $itemElement->single_price=$price;
                    $itemElement->total_price=$totalPrice;
                    $itemElement->save();
                }

            $orderContact = new OrderContactModel;
            $orderContact->order_id= $order->id;
            $orderContact->full_name = $request["order"]["orderContact"]["fullName"];
            $orderContact->phone_number = $request["order"]["orderContact"]["phoneNumber"];
            $orderContact->full_address = $request["order"]["orderContact"]["fullAddress"];
            $orderContact->zip_code = $request["order"]["orderContact"]["zipCode"];
            $orderContact->save();

            DB::commit();
        }
        catch(\Exception $ex)
        {
            DB::rollback();
            throw $ex;
        }
    }

    function calculatePrice($pizzaId, $sizeId)
    {
        $pizzaPrice=$this->pizza->find($pizzaId)->price;
        $sizePrice=$this->size->find($sizeId)->price;
        
        return $pizzaPrice + $sizePrice;
    }

    function calculateTotalPriceOrder($request)
    {
        $totalPriceOrder=$this->deliveryCost;
        for ($i = 0; $i < count($request["order"]["orderDetail"]); $i++) 
        {
            $pizza_id=$request["order"]["orderDetail"][$i]["idPizza"];
            $size_id=$request["order"]["orderDetail"][$i]["idSize"];
            $quantity=$request["order"]["orderDetail"][$i]["quantity"];

            $price=$this->calculatePrice($pizza_id, $size_id);
            $subTotalPrice=$price * $quantity;
            $totalPriceOrder=$totalPriceOrder + $subTotalPrice;
        }

        return $totalPriceOrder;
    }
}<file_sep>/database/seeds/SizeTableSeeder.php
<?php

use Illuminate\Database\Seeder;
use App\Size;

class SizeTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        Size::create([
            'name' => 'Individual',
            'price' => 0,
        ]);
        Size::create([
            'name' => 'Medium',
            'price' => 2,
        ]);
        Size::create([
            'name' => 'Big',
            'price' => 4,
        ]);
    }
}
<file_sep>/app/Http/Controllers/OrderController.php
<?php

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Services\Order as OrderService;

class OrderController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @param Request $request
     * @return void
     */
    public function __construct(OrderService $orderService)
    {
        $this->_orderService  = $orderService;
    }

     /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        return $this->_orderService->getAll();
    }

    /**
    * Store a newly created resource in order.
    *
    * @param  \Illuminate\Http\Request  $request
    * @return \Illuminate\Http\Response
    */
    public function create(Request $request)
    {
        $v = $this->_orderService->validator($request->all());
        if ($v->fails())
        {
            return response()->json($v->errors(), 400);
        }
        
        $this->_orderService->create($request->all());
        return response()->json("Order Created", 200);
    }

    /**
    * Display the specified resource.
    *
    * @param  int  $id
    * @return \Illuminate\Http\Response
    */
    public function show($id)
    {
        return $this->_orderService->get($id);
    }
}
<file_sep>/app/Http/Controllers/PizzaController.php
<?php

namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Services\Pizza as PizzaService;
use Illuminate\Http\Request;

class PizzaController extends Controller
{
   public function __construct(PizzaService $pizzaService)
   {
       $this->_pizzaService  = $pizzaService;
   }

   public function index()
   {
       return $this->_pizzaService->getAll();
   }

    /**Store a newly created resource in storage.
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
         $v = $this->_pizzaService->validator($request->all());
         if ($v->fails())
         {
            return response()->json($v->errors(), 400);
         }
         return $this->_pizzaService->create($request);
    }

     /*Display the specified resource.
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
     public function show($id)
     {
         return $this->_pizzaService->get($id);
     }

     /*Update the specified resource in storage.
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
     public function update(Request $request)
     {
      return $this->_pizzaService->update($request);
        
     }

    /*Remove the specified resource from storage.
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
     public function destroy($id)
     {
      return $this->_pizzaService->delete($id);
     }
}

<file_sep>/app/OrderDetail.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class OrderDetail extends Model
{
    protected $fillable = [
        'order_id', 'pizza_id', 'size_id', 'quantity', 'single_price', 'total_price'
    ];

    public function order()
    {
        return $this->belongsTo('App\Order');
    }
}
<file_sep>/app/Http/Controllers/ParameterController.php
<?php

namespace App\Http\Controllers;
use App\Services\Parameter as ParameterService;
use App\Http\Controllers\Controller;

class ParameterController extends Controller
{
    public function __construct(ParameterService $parameterService)
    {
        $this->_parameterService  = $parameterService;
    }

    public function index()
    {
        return $this->_parameterService->getAll();
    }
}
