query(request()->input())
->paginate(request("paginate") ?? 50);
$warehouses = Warehouse::query()->select("id","name")->get();
$owners = app("OwnerService")->getIntersectPermitting();
return view("store.deliveryAppointment.list",compact("list","warehouses","owners"));
}
public function appointment()
{
if(!Gate::allows('入库管理-入库预约-预约')){ return view("exception.authority"); }
$owners = app("OwnerService")->getIntersectPermitting();
$cars = CarType::query()->get();
$warehouses = Warehouse::query()->select("id","name")->get();
return view("store.deliveryAppointment.appointment",compact("owners","cars","warehouses"));
}
public function import()
{
$this->importExcel(new AppointmentDetail());
}
/**
* 获取产能
*
*/
public function getCapacity()
{
$this->gate("入库管理-入库预约-预约");
$model = request("model");
$errors = $this->appointmentValidator($model)->errors();
if (count($errors)>0)$this->success(["errors"=>$errors]);
/** @var \stdClass $warehouse */
$warehouse = Warehouse::query()->find($model["warehouse_id"]);
$tonne = $model["tonne"] ?? 0;
$cubicMeter = $model["cubic_meter"] ?? 0;
$amount = request("detail_amount");
$need = app("DeliveryAppointmentService")->calculateCapacity($tonne,$cubicMeter,$amount,$warehouse->reduced_production_capacity_coefficient);//所需产能
$start = Carbon::today();
$end = Carbon::today()->addDays(6);
$map = [];
DeliveryAppointment::query()->selectRaw("appointment_date,date_period,SUM(capacity) AS capacity")
->whereBetween("appointment_date",[$start->toDateString(),$end->toDateString()])
->whereIn("status",[0,2])
->where("warehouse_id",$warehouse->id)
->groupBy(["appointment_date","date_period"])->get()
->each(function ($appointment)use(&$map){
$map[$appointment->appointment_date."-".$appointment->date_period] = $appointment->capacity;
});
$list = [];
$capacity = $warehouse->production_capacity;
foreach (CarbonPeriod::create($start,$end) as $date){
/** @var $date Carbon */
$date = $date->format("Y-m-d");
$periods = [];
if ($date==date("Y-m-d")){
$hour = date("H");
foreach (DeliveryAppointment::PERIOD as $key=>$period){
$period = explode("-",$period);
$periodArr = ["time"=>$period[0].":00 - ".$period[1].":00","index"=>$key,"isAvailable"=>false];
if ($hour<$period[1]-1){
$total = $capacity*DeliveryAppointment::HOUR[$key];//仓库该时段产能总量
$used = $map[$date."-".$key] ?? 0; //已使用产能
$available = $total-$used; //可用产能
if ($available > $need)$periodArr["isAvailable"] = true;
}
$periods[] = $periodArr;
}
}else{
foreach (DeliveryAppointment::PERIOD as $key=>$period){
$period = explode("-",$period);
$period = $period[0].":00 - ".$period[1].":00";
$periodArr = ["time"=>$period,"index"=>$key,"isAvailable"=>false];
$total = $capacity*DeliveryAppointment::HOUR[$key];//仓库该时段产能总量
$used = $map[$date."-".$key] ?? 0; //已使用产能
$available = $total-$used; //可用产能
if ($available > $need)$periodArr["isAvailable"] = true;
$periods[] = $periodArr;
}
}
$list[] = ["date"=>$date,"period"=>$periods];
}
$this->success($list);
}
/**
* 确定预约
*/
public function submitAppointment()
{
$this->gate("入库管理-入库预约-预约");
$model = request("model");
$selectDate = request("date");
$details = request("details");
$errors = $this->appointmentValidator($model)->errors();
if (count($errors)>0)$this->success(["errors"=>$errors]);
$errors = Validator::make($selectDate,[
"date" => ["required","date","after:today"],
"time" => ["required","integer"],
])->errors();
if (count($errors)>0)$this->error("未选定预约日期");
DB::transaction(function ()use($model,$selectDate,$details,&$appointment){
$result = DeliveryAppointment::query()->selectRaw("appointment_date,date_period,SUM(capacity) AS capacity")
->where("appointment_date",$selectDate["date"])
->where("date_period",$selectDate["time"])
->where("warehouse_id",$model["warehouse_id"])
->where("status",0)
->groupBy(["appointment_date","date_period"])
->lockForUpdate()->first();
/** @var \stdClass $warehouse */
$warehouse = Warehouse::query()->find($model["warehouse_id"]);
$need = app("DeliveryAppointmentService")->
calculateCapacity($model["tonne"] ?? 0,$model["cubic_meter"] ?? 0,count($details),
$warehouse->reduced_production_capacity_coefficient);
if ($result){
$total = $warehouse->production_capacity*DeliveryAppointment::HOUR[$selectDate["time"]];
$available = $total-$result->capacity;
if ($available < $need)$this->success(["isFail"=>true]);
}
/** @var \stdClass $appointment */
$appointment = DeliveryAppointment::query()->create([
"user_id" => Auth::id(),
"owner_id" => $model["owner_id"],
"procurement_number" => $model["procurement_number"] ?? null,
"asn_number" => $model["asn_number"] ?? null,
"warehouse_id" => $model["warehouse_id"],
"tonne" => $model["tonne"] ?? 0,
"cubic_meter" => $model["cubic_meter"] ?? 0,
"box_amount" => $model["box_amount"] ?? 0,
"capacity" => $need,
"appointment_date" => $selectDate["date"],
"date_period" => $selectDate["time"],
]);
if ($details)app("DeliveryAppointmentService")->insertDetails($appointment,$details);
$insert = [];
foreach ($model["cars"] as $index=>$car){
$rand = mt_rand(0,9);
$len = strlen($appointment->id);
$ten = $len < 2 ? "0" : substr($appointment->id,$len-2,1);
$one = substr($appointment->id,$len-1,1);
//唯一码 随机数+十位+当前下标+个位+日期
$number = $rand.$ten.$index.$one.date("d");
$insert[] = [
"delivery_appointment_id" => $appointment->id,
"license_plate_number" => $car["license_plate_number"],
"car_id" => $car["car_id"] ?? null,
"driver_name" => $car["driver_name"] ?? null,
"driver_phone" => $car["driver_phone"] ?? null,
"appointment_number" => $number,
];
}
DeliveryAppointmentCar::query()->insert($insert);
});
dispatch(new DeliveryAppointmentCheck($appointment->id))->delay(Carbon::parse($appointment->appointment_date." ".(explode("-",DeliveryAppointment::PERIOD[$appointment->date_period])[1]).":00:01"));
//md5加密在密文第五位后插入
$md5 = substr_replace(md5(date("m-d")),$appointment->id,5,0);
$this->success(["key"=>$md5]);
}
private function appointmentValidator(array $model)
{
return Validator::make($model,[
"owner_id" => ["required","integer"],
"warehouse_id" => ["required","integer"],
"tonne" => ["required_without:cubic_meter","numeric"],
"cubic_meter" => ["required_without:tonne","numeric"],
"box_amount" => ["nullable","integer"],
"cars.*.license_plate_number" => ["required","size:7"],
"cars.*.car_id" => ["nullable","integer"],
"cars.*.driver_phone" => ["nullable"],
"cars.*.driver_name" => ["nullable"],
],[
'required'=>':attribute 不应为空',
'integer'=>':attribute 应为数值',
'required_without'=>':attribute 不应为空',
'numeric'=>':attribute 必须为数字',
'size'=>':attribute 非法',
],[
'owner_id'=>'货主',
'warehouse_id'=>'仓库',
'tonne'=>'吨',
'cubic_meter'=>'立方',
'cars.*.license_plate_number'=>'车牌号',
'cars.*.car_id'=>'车型',
'cars.*.driver_phone'=>'司机电话',
'cars.*.driver_name'=>'司机姓名',
]);
}
/**
* 根据key取id 鉴权数据
*/
public function showAppointmentInfo()
{
if(!Gate::allows('入库管理-入库预约-预约')){ return view("exception.authority"); }
$key = request("k");
$len = strlen($key);
$id = substr($key,5,$len-32);
$md5 = substr($key,0,5).substr($key,5+$len-32);
if ($md5!==md5(date("m-d")))return view("exception.404");
/** @var \stdClass $appointment */
$appointment = DeliveryAppointment::query()->with("cars")->find($id);
if (!$appointment || $appointment->user_id != Auth::id())return view("exception.404");
return view("store.deliveryAppointment.success",compact("appointment"));
}
/**
* 取消预约
*/
public function cancel()
{
$this->gate("入库管理-入库预约-预约");
$id = request("id");
if (!$id)$this->error("非法参数");
DeliveryAppointment::query()->where("status",0)->where("id",$id)->update(["status"=>1]);
$this->success(1);
}
/**
* 导出
*/
public function export()
{
if(!Gate::allows('入库管理-入库预约-预约管理')){ return view("exception.authority"); }
if (request("checkAllSign")){
$params = request()->input();
unset($params["checkAllSign"]);
$query = app("DeliveryAppointmentService")->query($params);
}else $query = app("DeliveryAppointmentService")->query(["id"=>request("id")]);
/** @var Builder $query */
$list = $query->with(["owner","warehouse"])->get();
$row = ["状态","货主","预约时间","仓库","预约号","车牌号","车型",
"司机姓名","司机电话","吨","立方","箱数","采购单号","ASN单号","商品名称","条码","数量","创建时间"];
foreach ($list as &$data){
$appointment = "";
$number = "";
$carType = "";
$driverName = "";
$driverPhone = "";
$commodityName = "";
$commodityCode = "";
$amount = "";
foreach ($data->cars as $car){
$appointment .= $car->appointment_number."\r\n";
$number .= $car->license_plate_number."\r\n";
$carType .= ($car->car->name ?? '')."\r\n";
$driverName .= ($car->driver_name ?? '')."\r\n";
$driverPhone .= ($car->driver_phone ?? '')."\r\n";
}
foreach ($data->details as $detail){
$commodityName .= ($detail->commodity->name ?? $detail->name)."\r\n";
$commodityCode .= ($detail->commodity->barcodes->code ?? $detail->bar_code)."\r\n";
$amount .= $detail->amount."\r\n";
}
$data = [
DeliveryAppointment::STATUS[$data->status],
$data->owner->name ?? '',
$data->appointment_date,
$data->warehouse->name ?? '',
$appointment,
$number,
$carType,
$driverName,
$driverPhone,
$data->tonne,
$data->cubic_meter,
$data->box_amount,
$data->procurement_number,
$data->asn_number,
$commodityName,
$commodityCode,
$amount,
$data->created_at
];
}
return app(ExportService::class)->json($row,$list,"预约记录");
}
private function carList($period,$date,$warehouse)
{
$list = [];
DeliveryAppointmentCar::query()->with(["deliveryAppointment"=>function($query){
/** @var Builder $query */
$query->withCount("cars");
}])->whereHas("deliveryAppointment",function ($query)use($period,$warehouse,$date){
/** @var Builder $query */
$query->where("appointment_date",$date)
->where("warehouse_id",$warehouse)->whereIn("status",[0,2]);
})->where(function ($query)use($period){
/** @var Builder $query */
$query->where("status",1)->orWhereHas("deliveryAppointment",function (Builder $query)use($period){
$query->where("date_period",">=",$period);
});
})->orderByRaw("(CASE WHEN status=0 THEN 2 WHEN status=2 THEN 3 END),IF(ISNULL(delivery_time),1,0),delivery_time")
->limit(10)->get()->each(function ($car)use(&$list){
//$diff = $car->delivery_time ? (strtotime($car->delivery_time)+1799)-time() : 0;
$count = $car->deliveryAppointment->cars_count ?? 0;
$list[] = [
"id" => $car->id,
"license_plate_number" => $car->license_plate_number,
"driver_name" => $car->driver_name,
"driver_phone" => $car->driver_phone,
"status" => $car->status,
"cubic_meter" => isset($car->deliveryAppointment->cubic_meter) && $car->deliveryAppointment->cubic_meter>0 ? ($count>1 ? $car->deliveryAppointment->cubic_meter."/".$count : $car->deliveryAppointment->cubic_meter) : "",
"tonne" => isset($car->deliveryAppointment->tonne) && $car->deliveryAppointment->tonne>0 ? ($count>1 ? $car->deliveryAppointment->tonne."/".$count : $car->deliveryAppointment->tonne) : "",
//"diff" => $diff>0 ? $diff*1000 : 0,
];
});
return $list;
}
/**
* 获取展览数据
*/
public function getExhibitionList()
{
$this->gate("入库管理-入库预约-入库区终端");
$hour = date("H");
$warehouse = request("warehouse");
$index = null;
foreach (DeliveryAppointment::PERIOD as $key=>$period){
$arr = explode("-",$period);
if (count($arr)!=2)continue;
if ($hour<$arr[1]){
$index = $key;
break;
}
}
if ($index===null)$this->success();
$list = $this->carList($index,date("Y-m-d"),$warehouse);
$counts = DeliveryAppointmentCar::query()->whereHas("deliveryAppointment",function (Builder $query)use($index,$warehouse){
$query->where("appointment_date",date("Y-m-d"))
->where("warehouse_id",$warehouse)->whereIn("status",[0,2]);
})->selectRaw("status, COUNT(1) AS c")->groupByRaw("status")->get();
$success = 0;
$work = 0;
$notReached = 0;
if ($counts)foreach ($counts as $c){
switch ($c->status){
case 0:
$notReached = $c->c;
break;
case 1:
$work = $c->c;
break;
case 2:
$success = $c->c;
break;
}
}
$result = ["list"=>$list,"success"=>$success,"work"=>$work,"notReached"=>$notReached,"nextDay"=>$this->carList(0,date("Y-m-d",strtotime("+1 day")),$warehouse)];
$nextTime = DeliveryAppointment::PERIOD[$index+1] ?? null;
if ($nextTime){
$nextTime = explode("-",$nextTime)[0];
$timestamp = strtotime(date("Y-m-d")." ".$nextTime.":00:00");
$result["refresh"] = (($timestamp-time())*1000) ?? 1000;
}
$this->success($result);
}
public function getKey()
{
$this->success(app("DeliveryAppointmentService")->getKey());
}
/**
* 错误信息
*
* @return string
*/
public function errMsg()
{
return <<
×
二维码已过期,请重新扫描!