| Server IP : 34.87.99.72 / Your IP : 216.73.217.31 Web Server : Apache/2.4.46 (Unix) OpenSSL/1.1.1n System : Linux zlock-bitnami-lamp-prod-v2-vm 4.19.0-16-cloud-amd64 #1 SMP Debian 4.19.181-1 (2021-03-19) x86_64 User : bitnami ( 1000) PHP Version : 7.4.18 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /opt/bitnami/apache/htdocs/app/app/Models/ |
Upload File : |
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Casts\AsArrayObject;
use Pylon\Traits\Models\HasSearchScope;
use Carbon\Carbon;
use App\Classes\Polarity;
use Illuminate\Support\Facades\Crypt;
use Auth;
use App\Models\UserBoxBooking;
class UserBoxDelivery extends Model
{
use HasSearchScope;
protected $fillable = [
"tracking_num",
"delivery_depot_code",
"primary_sort_code",
"secondary_sort_code",
"parcel_info",
"parcel_length",
"parcel_width",
"parcel_height",
"parcel_weight",
"dropper_name",
"dropper_num",
"receiver_name",
"receiver_email",
"receiver_num",
"receiver_house_num",
"receiver_address",
"receiver_postcode",
"receiver_email",
"receiver_city",
"receiver_state",
"remarks",
"expired_at",
"collected_at",
];
protected $casts = [
"meta" => AsArrayObject::class,
];
//EMAIL ALERT FOR DELIVERY ORDER
const EMAIL_ALERT = [
"naresh@zlock.com.my",
"aaron@zlock.com.my",
"benjamin@zlock.com.my",
"koffee@zlock.com.my",
"vogue@zlock.com.my",
"samuel@advisoryapps.com"
];
const EMAIL_ALERT_DEV = [
"samuel@advisoryapps.com"
];
// RSERVED MINUTES FOR DELIVERY - 24 HOURS
const MAX_RESERVED_MINUTES = 1440;
//LOCKER DELIVERY FUNCTION ONLINE TIME
const START_TIME = '08:00:00';
const END_TIME = '22:00:00';
//LOCKER DELIVERY OFF DAYS
const OFF_DAYS = [0]; // (SUNDAY)
//PARCEL TYPES
const PARCEL = 1;
const DOCUMENT = 2;
public const PARCEL_TYPES = [
self::PARCEL => "Parcel",
self::DOCUMENT => "Document",
];
//PARCEL RULES
const MIN_WEIGHT = 0.01; //10 Jun 2025 - Add minimum weight for parcel
const WEIGHT_LIMIT = 20;
const DROPPER = 2;
public const TYPES = [
self::DROPPER => "Dropper",
];
const END_BY_SYSTEM = 1;
const END_BY_DROPPER = 2;
const END_BY_COLLECTOR = 3;
const END_BY_STAFF = 4;
public const ENDED_TYPES = [
self::END_BY_SYSTEM => "System",
self::END_BY_DROPPER => "Dropper",
self::END_BY_COLLECTOR => "Collector",
self::END_BY_STAFF => "Staff",
0 => null,
];
// append
protected $appends = ['status', 'booking_type', 'parcel_dimension', 'parcel_type_info', 'reserved_minute', 'unique_id'];
// accessor
public function getInventoryTypeAttribute()
{
return self::TYPES[$this->attributes['inventory_type_id']] ?? 'N/A';
}
public function getParcelTypeInfoAttribute()
{
if(isset(self::PARCEL_TYPES[$this->parcel_type]))
return self::PARCEL_TYPES[$this->parcel_type];
return 'undefined';
}
public function getUniqueIdAttribute()
{
return $this->userBoxBooking ? $this->userBoxBooking->unique_id : null;
}
public function getReservedMinuteAttribute()
{
return self::MAX_RESERVED_MINUTES;
}
public function getStatusAttribute()
{
return self::computeStatus();
}
public function getBookingTypeAttribute()
{
return 'delivery';
}
public function getDeliveryBookingFeeAttribute()
{
return self::computeDeliveryBookingFee();
}
public function getTotalBookingFeeAttribute()
{
return self::computeTotalBookingFee();
}
public function getTotalBookingFeePartnerAttribute()
{
return self::computeTotalBookingFeePartner();
}
public function getTotalUsageTimeAttribute()
{
return self::computeTotalUsageTime();
}
public function getParcelDimensionAttribute()
{
if(isset($this->attributes['parcel_length']) && isset($this->attributes['parcel_width']) && isset($this->attributes['parcel_height'])){
return "{$this->attributes['parcel_length']} x {$this->attributes['parcel_width']} x {$this->attributes['parcel_height']} (cm)";
}
return null;
}
// relationship
public function user()
{
return $this->belongsTo('App\Models\User', 'user_id');
}
public function box()
{
return $this->belongsTo('App\Models\LockerBox', 'box_id');
}
public function locker()
{
return $this->belongsToMany('App\Models\Locker', 'locker_boxes', 'id', 'locker_id', 'box_id');
}
public function recordedLocker()
{
return $this->belongsTo('App\Models\Locker', 'recorded_locker_id');
}
public function deliveryPartner()
{
return $this->belongsTo('App\Models\Courier', 'delivery_partner_id');
}
public function userBoxBooking()
{
return $this->morphOne('App\Models\UserBoxBooking', 'orderable');
}
// functions
public function getInventoryType($user){
$item = $this;
$is_owner = ($item->user_id == $user->id);
$item->inventory_type_id = UserBoxInventory::DROPPER ;
}
public function dropper()
{
return $this->user();
}
public function isExpired($now = null ){
if($now == null){
$now = now();
}
$expired_at = new Carbon($this->attributes['expired_at']);
return $now->greaterThan($expired_at);
}
public function getQrCode()
{
$item = $this;
$item->qr_code = null;
$item->cancel_qr_code = null;
$user_id = Auth::user()->id;
if($item->isDropOff())
{
$json_string = json_encode([
'id' => $item->id,
'booking_type' => $item->booking_type,
'type' => UserBoxBooking::DROP_OFF_ACTION,
'user_id' => $user_id,
]);
$item->qr_code = base64_encode($json_string);
}
if($item->isCancelQr())
{
$json_string = json_encode([
'id' => $item->id,
'booking_type' => $item->booking_type,
'type' => UserBoxBooking::CANCEL_ORDER_ACTION,
'user_id' => $user_id,
]);
$item->cancel_qr_code = base64_encode($json_string);
}
}
public function computeStatus()
{
$item = $this->attributes;
$tracking_url = null;
if($item['collected_at'] != null){
$polar_id = Polarity::NEGATIVE;
$message = "N/A";
switch ($item['ended_type']) {
case self::END_BY_SYSTEM:
$message = "Cancelled by system";
break;
case self::END_BY_DROPPER:
$message = "Cancelled by dropper";
break;
case self::END_BY_COLLECTOR:
$polar_id = Polarity::POSITIVE;
$message = "Picked up by " . $this->deliveryPartner->name;
if($item['tracking_num'] != $item['id'])
$tracking_url = $this->deliveryPartner->url . $item['tracking_num'];
break;
case self::END_BY_STAFF:
$message = "Cancelled by staff";
break;
}
return [ "polar_id" => $polar_id, "message" => $message, "tracking_url" => $tracking_url ];
}
$polar_id = Polarity::NEUTRAL;
if($item['dirty_at'] == null){
$pending_msg = "Pending drop off";
}else{
$pending_msg = "Pending pick up";
}
if($this->isExpired()){
$polar_id = Polarity::NEGATIVE;
$pending_msg = $pending_msg."(Expired)";
}
return [
"polar_id" => $polar_id,
"message" => $pending_msg,
"tracking_url" => $tracking_url
];
}
public function computeTotalUsageTime()
{
$item = $this->attributes;
if($item['collected_at'] == null){
return null;
}
$startTime = Carbon::parse($item['created_at']);
$finishTime = Carbon::parse($item['collected_at']);
return $finishTime->diffInMinutes($startTime);
}
public function computeDeliveryBookingFee()
{
$item = json_decode($this->attributes['meta']);
return number_format(((float)$item->final_price), 2, '.', '');
}
public function computeTotalBookingFee()
{
$item = json_decode($this->attributes['meta']);
return number_format(((float)$item->locker_price), 2, '.', '');
}
public function computeTotalBookingFeePartner()
{
$item = json_decode($this->attributes['meta']);
if(isset($item->locker_price_partner))
$totalBookingFeePartner = $item->locker_price_partner;
else
$totalBookingFeePartner = 0;
return number_format($totalBookingFeePartner, 2, '.', '');
}
public function isDropOff()
{
return $this->dirty_at == null;
}
public function isCancelQr()
{
return $this->dirty_at != null;
}
}