ewa / app /Services /BookingServices.php
df
gmail api
992488d
<?php
namespace App\Services;
use App\Enums\BookingStatus;
use App\Mails\BookingMail;
use App\Models\Booking as BookingModel;
use Carbon\Carbon;
use Dacastro4\LaravelGmail\Services\Message\Mail;
use Illuminate\Support\Facades\Storage;
use phpseclib3\File\ASN1\Maps\Extension;
use stdClass;
class BookingServices extends BaseServices
{
private $roomTypePacketServices;
private $roomServices;
private $roomBookingServices;
private $paymentServices;
private $packetServices;
public function __construct(BookingModel $model,
RoomTypePacketServices $roomTypePacketServices,
RoomServices $roomServices,
RoomBookingServices $roomBookingServices,
PaymentServices $paymentServices,
PacketServices $packetServices)
{
parent::__construct($model);
$this->roomTypePacketServices = $roomTypePacketServices;
$this->roomServices = $roomServices;
$this->roomBookingServices = $roomBookingServices;
$this->paymentServices = $paymentServices;
$this->packetServices = $packetServices;
}
public function index($request, $customerId = null)
{
$limit = $request->get("limit");
$query_array = $request->query();
$query = $this->model;
$status = $query_array['status'] ?? "";
if (!empty($status)) {
$query = $query->where('status', $status);
}
if ($customerId && !empty($customerId)) {
$query = $query->where("customer_id", $customerId);
// $query->with('customer', function ($query) use ($customerId) {
// $query->where('id', $customerId);
// });
}
$query->with("payments", function ($query) {
$query->select("payments.id", "payments.payment_date",
"payments.email", "payments.address",
"payments.payment_method", "payments.description",
"payments.payment_amount", "payments.booking_id");
});
$query->with("rooms", function ($query) {
$query->select("rooms.id", "rooms.room_view",
"rooms.room_number", "rooms.room_type_packet_id");
});
$query->select("id", "checkout_at", "checkin_at", "total_price"
, "number_guests", "status", "cancel_reason");
$query = $query->orderBy('updated_at', 'desc');
$rs = empty($limit) ? ($query->get()) : ($query->paginate($limit));
$this->prepareRoom($rs);
return $rs;
}
public function prepareRoom(&$booking)
{
$booking->each(function ($item) {
$this->roomServices->getRoomByIdsAndPacket($item);
});
}
public function getBookingByNotAvailble($param)
{
$from_time = $param['checkin_at'];
$to_time = $param['checkout_at'];
$query = $this->model;
$query = $query->whereHas('bookingStatus', function ($query) {
$query->where('name', '!=', BookingStatus::getKey(BookingStatus::CANCEL));
});
$query->where(function ($query) use ($from_time, $to_time) {
$query->orwhere(function ($query) use ($from_time, $to_time) {
$query
->whereRaw("bookings.checkin_at <= STR_TO_DATE(?, '%Y-%m-%d %H:%i:%s')", $from_time)
->whereRaw("bookings.checkout_at >= STR_TO_DATE(?, '%Y-%m-%d %H:%i:%s')", $from_time);
});
$query->orwhere(function ($query) use ($from_time, $to_time) {
$query
->whereRaw("bookings.checkin_at >= STR_TO_DATE(?, '%Y-%m-%d %H:%i:%s')", $from_time)
->whereRaw("bookings.checkin_at <= STR_TO_DATE(?, '%Y-%m-%d %H:%i:%s')", $to_time);
});
});
return $query->get();
}
public function makeCheckout($request)
{
// todo: tính lại total price dựa vào giá phòng, và giá packet
// todo: nhận về id room type, list id packet, tìm ra các room ứng với dữ liệu trên
// todo: thuế đc lấy từ db ?
// nếu số lượng room search nhỏ hơn số lượng room cần đăt , thì báo lỗi
// 1. tạo 1 record booking với thông tin booking
// nếu dữ liệu của paymentamount bằng với total price, thì set status là complete
// nhỏ hơn thì set partialy paid , nếu paymentamount = 0 thì set pending
// 2. tạo reocrd bookin_room với id booking và id room
// 3. tạo record payment với id booking
$gstRate = 0.12;
$totalPrice = 0;
$roomTypeId = $request["room"]["id"];
$numberRoom = count($request["packets"]);
$packets = [];
$paymentAmount = $request["payment"]["payment_amount"] ?? 0;
foreach ($request["packets"] as $item) {
$packets[] = $item["id"];
}
$isStopBooking = false;
$booking = [];
$hashCheck = [];
// tạo dữ liệu số lượng packet ứng với packet
foreach ($packets as $packet) {
if (isset($hashCheck[$packet])) {
$hashCheck[$packet] += 1;
} else {
$hashCheck[$packet] = 1;
}
}
// tinh tong tien
$checkout_at = Carbon::createFromFormat('Y-m-d', $request["checkout_at"]);
$checkin_at = Carbon::createFromFormat('Y-m-d', $request["checkin_at"]);
$bookingPeriodDays = $checkout_at->diff($checkin_at)->days;
$bookingPeriodDays = $bookingPeriodDays > 0 ? $bookingPeriodDays : 1;
$roomTypeService = app()->make(RoomTypeServices::class);
$tmp_packets = $this->packetServices->getPacketByIds($packets);
$roomType = $roomTypeService->getRoomTypeById($roomTypeId);
if (!$roomType || $isStopBooking) {
throw new \Exception("room not available");
}
$roomTypePrice = $roomType->base_price ?? 0;
$tmp_packets->each(function ($packet) use (&$totalPrice, $roomTypePrice, $bookingPeriodDays, $hashCheck) {
$totalPrice += (($packet->base_price) + $roomTypePrice) * $hashCheck[$packet->id] * $bookingPeriodDays;
});
$totalPrice = ($totalPrice * $gstRate) + $totalPrice;
$roomAvailable = collect();
foreach ($hashCheck as $key => $value) {
// lấy ra roomtypepacket ứng với packet roomtype
$roomTypePackets = $this->roomTypePacketServices->getRoomTypePacketByRoomTypeAndPacket($roomTypeId, $key)->pluck("id");
if (count($roomTypePackets) < 1) {
$isStopBooking = true;
break;
}
// điều kiện booking về ngày check in phải thõa
$bookings = $this->getBookingByNotAvailble($request)->pluck("id");
// lấy ra room thõa đk booking, và thõa đk room type
$rooms = $this->roomServices->getRoomByRoomTypePacketsAndBooking($roomTypePackets, $bookings);
// nếu số room tìm đc nhỏ hơn số room muốn đặt thì lỗi
if ($rooms->count() < $value) {
$isStopBooking = true;
break;
} else {
$rooms = $rooms->take($value);
$roomAvailable = $roomAvailable->merge($rooms);
}
}
if ($isStopBooking) {
throw new \Exception("room not available");
}
if ($paymentAmount == 0) {
$booking["status"] = BookingStatus::PENDING;
} else if ($totalPrice > $paymentAmount) {
$booking["status"] = BookingStatus::PENDING;
} else if ($paymentAmount >= $totalPrice) {
$booking["status"] = BookingStatus::PENDING;
}
$booking["customer_id"] = $this->getCurrentUser()->id;
$booking["checkin_at"] = $request["checkin_at"];
$booking["checkout_at"] = $request["checkout_at"];
$booking["total_price"] = $totalPrice;
$booking["number_guests"] = $request["guests"];
$booking = $this->save($booking);
if (!$booking || $isStopBooking) {
throw new \Exception("booking not available");
}
$roomBookings = collect();
// các room thõa đk có thể đặt phòng
$roomAvailable->each(function ($room) use ($booking, &$roomBookings) {
$roomBooking = [
"booking_id" => $booking->id,
"room_id" => $room->id,
"room_type_packet_id" => $room->room_type_packet_id
];
$roomBooking = $this->roomBookingServices->save($roomBooking);
if (!$roomBooking) {
$isStopBooking = true;
return false;
}
$roomBookings->push($roomBooking);
});
if ($isStopBooking) {
throw new \Exception("booking not available");
}
$payment = [
"booking_id" => $booking->id,
"payment_date" => $request["payment"]["payment_date"] ?? "",
"payment_method" => $request["payment"]["payment_method"] ?? "",
"description" => $request["payment"]["description"] ?? "",
"payment_amount" => $paymentAmount,
"address" => $request["payment"]["address"] ?? "",
"email" => $request["payment"]["email"] ?? "",
"city" => $request["payment"]["city"] ?? "",
"state" => $request["payment"]["state"] ?? "",
"post_code" => $request["payment"]["post_code"] ?? ""
];
$payment = $this->paymentServices->save($payment);
if (!$payment || $isStopBooking) {
throw new \Exception("payment not available");
}
$booking->rooms = $roomAvailable;
$this->roomServices->getRoomByIdsAndPacket($booking);
$gmailProvider = new Mail;
$gmailProvider->from('lisatthu35@gmail.com');
$gmailProvider->subject( "noreply-mail" );
$gmailProvider->to($payment->email);
$mailableInstance = new BookingMail($booking,$payment, "Thông tin đơn đặt phòng");
$gmailProvider->message($mailableInstance->render());
$gmailProvider->send();
//Mail::to($payment->email)->send(new BookingMail($booking,$payment, "Thông tin đơn đặt phòng"));
return $booking;
}
public function show($id)
{
$data = $this->model->where('id', $id)->first();
return $data;
}
public function save(array $attributes)
{
$mailSubject = false;
$entity = null;
if (!empty($attributes['id'])) {
$entity = $this->model->where('id', $attributes['id'])->first();
if ($entity) {
$entity->fill($attributes)->save();
if ($entity->status === BookingStatus::CANCEL) {
$mailSubject = "Đơn đặt phòng đã bị từ chối";
}
if ($entity->status === BookingStatus::COMPLETED) {
$mailSubject = "Đơn đặt phòng đã thành công";
}
}
} else {
$entity = $this->model->create($attributes);
}
if ($mailSubject) {
$gmailProvider = new Mail;
$gmailProvider->from('lisatthu35@gmail.com');
$gmailProvider->subject( "noreply-mail" );
$gmailProvider->to($entity->payments[0]->email);
$mailableInstance = new BookingMail($entity, $entity->payments[0], $mailSubject);
$gmailProvider->message($mailableInstance->render());
$gmailProvider->send();
//Mail::to($entity->payments[0]->email)->send(new BookingMail($entity, $entity->payments[0], $mailSubject));
}
return $entity;
}
public function delete($id)
{
$entity = $this->model
->where('id', $id)->first();
return !empty($entity) ? $entity->delete() : null;
}
}