|
|
<?php
|
|
|
|
|
|
|
|
|
namespace App\Http\Controllers\Manager;
|
|
|
|
|
|
use AlicFeng\IdentityCard\InfoHelper;
|
|
|
use App\Actions\AttachAffectedOrders;
|
|
|
use App\Actions\ChangeOrderStatus;
|
|
|
use App\Customer;
|
|
|
use App\Events\OrderAssigned;
|
|
|
use App\Libs\AlipayF2F;
|
|
|
use App\Libs\WxMicroPay;
|
|
|
use App\Models\Area;
|
|
|
use App\Models\Balance;
|
|
|
use App\Models\Bed;
|
|
|
use App\Models\OrderAgreement;
|
|
|
use App\Models\OrderItems;
|
|
|
use App\Models\Orders;
|
|
|
use App\Models\Paramedic;
|
|
|
use App\Models\ParamedicLevel;
|
|
|
use App\Models\Patient;
|
|
|
use App\Models\Product;
|
|
|
use App\Models\ProductItems;
|
|
|
use App\Models\ProductParamedicLevel;
|
|
|
use App\Models\Project;
|
|
|
use App\Models\Recharge;
|
|
|
use App\Models\Refund;
|
|
|
use Carbon\Carbon;
|
|
|
use Illuminate\Http\Request;
|
|
|
use Illuminate\Support\Facades\DB;
|
|
|
use Illuminate\Support\Facades\Log;
|
|
|
use Intervention\Image\Facades\Image;
|
|
|
use SimpleSoftwareIO\QrCode\Facades\QrCode;
|
|
|
use function GuzzleHttp\Psr7\str;
|
|
|
|
|
|
class OrdersController extends CommonController
|
|
|
{
|
|
|
/**
|
|
|
* @OA\Get(
|
|
|
* path="/manager/get-projects",
|
|
|
* tags={"管理端订单处理"},
|
|
|
* summary="V2 获取医院列表",
|
|
|
* description="获取医院列表",
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="获取医院列表"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
|
|
|
public function getProjects()
|
|
|
{
|
|
|
$projects = (new Project())
|
|
|
->join("manager_project", 'project.id', '=', 'manager_project.project_id')
|
|
|
->join('managers', 'managers.id', '=', 'manager_project.manager_id')
|
|
|
->whereRaw("managers.id = " . $this->manager->id)
|
|
|
->select("project.id", "project.name", "project.address", "project.latitude", "project.longitude")
|
|
|
->get();
|
|
|
return response()->json($projects->toArray());
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\Get(
|
|
|
* path="/manager/get-care-product/{project_id}",
|
|
|
* tags={"管理端订单处理"},
|
|
|
* summary="V2-获取产品详情",
|
|
|
* description="获取产品详情",
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Parameter(name="project_id", in="path", @OA\Schema(type="integer"), required=true, description="project_id"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="获取产品详情"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
|
|
|
public function getCareProduct($project_id)
|
|
|
{
|
|
|
DB::enableQueryLog();
|
|
|
$product = (new Product())->where("project_id", $project_id)->with([
|
|
|
"productItems" => function ($query) {
|
|
|
$query->select("id", "name", "product_id", "patient_quantity", "price");
|
|
|
},
|
|
|
"productParamedicLevels" => function ($query) {
|
|
|
$query
|
|
|
->select("product_paramedic_level.id", "product_paramedic_level.product_id", "product_paramedic_level.price")
|
|
|
->leftJoin("paramedic_level", "product_paramedic_level.paramedic_level_id", "=", "paramedic_level.id")
|
|
|
->addSelect("paramedic_level.name as paramedic_level_name");
|
|
|
},
|
|
|
"factors" => function ($query) {
|
|
|
$query->with(["factorItems" => function ($query) {
|
|
|
$query->select("id", "name", "factor_id", "price", "myindex")->orderBy("myindex");
|
|
|
}])->select("id", "name", "product_id")->orderBy("myindex");
|
|
|
}])
|
|
|
->leftJoin("project", "project.id", "=", "product.project_id")
|
|
|
->select("product.id", "product.name", "product.project_id", "project.name as project_name")->first();
|
|
|
return response()->json($product->toArray());
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\Get(
|
|
|
* path="/manager/get-project-orders-count/{project_id}",
|
|
|
* tags={"管理端订单处理"},
|
|
|
* summary="V2-获取医院订单数量角标",
|
|
|
* description="获取医院订单数量角标",
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Parameter(name="project_id", in="query", @OA\Schema(type="integer"), required=true, description="医院id"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="获取医院订单数量角标"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
|
|
|
public function getProjectOrdersCount($project_id)
|
|
|
{
|
|
|
$orders_count = [];
|
|
|
$orders_count["all"] = (new Orders())->ofProject($project_id)->count();
|
|
|
$orders_count["pending"] = (new Orders())->ofProject($project_id)->whereIn("status", [Orders::STATUS_UNCONFIRMED, Orders::STATUS_UNASSIGNED])->count();
|
|
|
$orders_count["ongoing"] = (new Orders())->ofProject($project_id)->where("status", Orders::STATUS_ONGOING)->count();
|
|
|
$orders_count["finished"] = (new Orders())->ofProject($project_id)->where("status", Orders::STATUS_FINISHED)->count();
|
|
|
|
|
|
return response()->json(compact("orders_count"));
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\Get(
|
|
|
* path="/manager/get-projcet-orders/{project_id}",
|
|
|
* tags={"管理端订单处理"},
|
|
|
* summary="V2-获取订单列表",
|
|
|
* description="获取订单列表",
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Parameter(name="project_id", in="path", @OA\Schema(type="integer"), required=false, description="医院ID"),
|
|
|
* @OA\Parameter(name="keyword", in="query", @OA\Schema(type="string"), required=false, description="查询关键词"),
|
|
|
* @OA\Parameter(name="building_id", in="query", @OA\Schema(type="integer"), required=false, description="楼栋ID"),
|
|
|
* @OA\Parameter(name="area_id", in="query", @OA\Schema(type="integer"), required=false, description="病区ID"),
|
|
|
* @OA\Parameter(name="start_date_from", in="query", @OA\Schema(type="string"), required=false, description="开始服务日期区间查询的第一个值"),
|
|
|
* @OA\Parameter(name="start_date_to", in="query", @OA\Schema(type="string"), required=false, description="开始服务日期区间查询的第二个值"),
|
|
|
* @OA\Parameter(name="days", in="query", @OA\Schema(type="integer"), required=false, description="服务天数,以实际生成的to_date和from_date比对为准,改价为0的也算"),
|
|
|
* @OA\Parameter(name="page", in="query", @OA\Schema(type="integer"), required=false, description="当前页码,默认为1"),
|
|
|
* @OA\Parameter(name="page_size", in="query", @OA\Schema(type="integer"), required=false, description="每页数量,默认为5"),
|
|
|
* @OA\Parameter(name="status", in="query", @OA\Schema(type="string"), required=false, description="订单状态:[pending=>待处理,ongoing=>进行中,finished=>已完成]"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="获取订单列表"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
|
|
|
public function list($project_id)
|
|
|
{
|
|
|
$model = $this->_getOrderModel();
|
|
|
$model = $model->ofProject($project_id);
|
|
|
if (request()->keyword) {
|
|
|
$keyword = request()->keyword;
|
|
|
$model = $model->where(function ($query) use ($keyword) {
|
|
|
$query
|
|
|
->where("serial", "like", "%{$keyword}%")
|
|
|
->orWhereHas("patient", function ($query) use ($keyword) {
|
|
|
$query->where("name", "like", "%{$keyword}%");
|
|
|
})->orWhereHas("customer", function ($query) use ($keyword) {
|
|
|
$query->where("mobile", "like", "%{$keyword}%");
|
|
|
})->orWhereHas("paramedic", function ($query) use ($keyword) {
|
|
|
$query->where("name", "like", "%{$keyword}%");
|
|
|
});
|
|
|
});
|
|
|
}
|
|
|
|
|
|
if (request()->area_id) {
|
|
|
$model = $model->whereHas("bed", function ($query) {
|
|
|
$query->where("area_id", request()->area_id);
|
|
|
});
|
|
|
} elseif (request()->building_id) {
|
|
|
$model = $model->whereHas("bed", function ($query) {
|
|
|
$query->where("building_id", request()->building_id);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
if (request()->bed_id) {
|
|
|
$model = $model->where('bed_id', request()->bed_id);
|
|
|
}
|
|
|
|
|
|
if (request()->days) {
|
|
|
$model = $model->whereRaw(DB::raw("datediff(`to_date`,`from_date`) = " . (request()->days - 1)));
|
|
|
}
|
|
|
|
|
|
if (request()->start_date_from && request()->start_date_to) {
|
|
|
$model = $model->whereRaw(DB::raw("UNIX_TIMESTAMP(`from_date`) between " . strtotime(request()->start_date_from) . " and " . strtotime(request()->start_date_to)));
|
|
|
}
|
|
|
|
|
|
switch (request()->status) {
|
|
|
case "pending":
|
|
|
$model = $model->whereIn("status", [Orders::STATUS_UNCONFIRMED, Orders::STATUS_UNASSIGNED]);
|
|
|
break;
|
|
|
case "ongoing":
|
|
|
case "finished":
|
|
|
$model = $model->where("status", constant(Orders::class . "::STATUS_" . strtoupper(request()->status)));
|
|
|
break;
|
|
|
default:
|
|
|
//do nothing
|
|
|
}
|
|
|
|
|
|
$page_size = request()->page_size ?? 5;
|
|
|
$data = $model->orderBy("id", "desc")->paginate($page_size);
|
|
|
foreach ($data as $order) {
|
|
|
$order = $order->refreshTotal();
|
|
|
$order->balance = $order->customer->balance;
|
|
|
}
|
|
|
return response()->json($data->toArray());
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\Get(
|
|
|
* path="/manager/get-affected-orders/{from_order_id}",
|
|
|
* tags={"管理端订单处理"},
|
|
|
* summary="V2-获取被影响到的订单列表",
|
|
|
* description="获取被影响到的订单列表",
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Parameter(name="from_order_id", in="path", @OA\Schema(type="intger"), required=true, description="因为某张订单造成了影响"),
|
|
|
* @OA\Parameter(name="from_paramedic_id", in="query", @OA\Schema(type="intger"), required=false, description="原护工的id"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="获取被影响到的订单列表"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
|
|
|
public function getAffectedOrders($from_order_id, Request $request)
|
|
|
{
|
|
|
$order = Orders::find($from_order_id);
|
|
|
$order = (new AttachAffectedOrders())($order, $request->from_paramedic_id);
|
|
|
return response()->json($order->affected_orders->toArray());
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\post(
|
|
|
* path="/manager/update-order-price",
|
|
|
* tags={"管理端订单处理"},
|
|
|
* summary="V2-批量更新订单价格",
|
|
|
* description="批量更新订单价格",
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Parameter(name="available_day", in="query", @OA\Schema(type="string"), required=false, description="生效日期,仅当值为today表示同步更新当日子订单价格,为其他值表示次日起生效"),
|
|
|
* @OA\Parameter(name="price", in="query", @OA\Schema(type="object"), required=true, description="价格提交,[{order_id:1,price:200},{...}]"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="批量更新订单价格"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
|
|
|
public function updateOrderPrice(Request $request)
|
|
|
{
|
|
|
DB::beginTransaction();
|
|
|
try {
|
|
|
$price = (array)json_decode($request->price, true);
|
|
|
if (!$price) {
|
|
|
return response()->json([
|
|
|
"errorcode" => "103",
|
|
|
"errormsg" => "错误的价格参数"
|
|
|
]);
|
|
|
}
|
|
|
$updated = [];
|
|
|
foreach ($price as $item) {
|
|
|
$order = Orders::find($item["order_id"]);
|
|
|
$order->update([
|
|
|
"price" => $item["price"]
|
|
|
]);
|
|
|
$updated[] = $order;
|
|
|
if ($request->available_day != "today") {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
//更新子订单
|
|
|
$res = (new OrderItems())->updateTodayItem($item["order_id"]);
|
|
|
if (!$res["status"]) {
|
|
|
return response()->json([
|
|
|
"errorcode" => "103",
|
|
|
"errormsg" => $res["msg"]
|
|
|
]);
|
|
|
}
|
|
|
}
|
|
|
DB::commit();
|
|
|
return response()->json($updated);
|
|
|
} catch (\Exception $exception) {
|
|
|
DB::rollBack();
|
|
|
return response()->json([
|
|
|
"errorcode" => $exception->getCode(),
|
|
|
"errormsg" => $exception->getMessage()
|
|
|
]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\Get(
|
|
|
* path="/manager/get-order/{id}",
|
|
|
* tags={"管理端订单处理"},
|
|
|
* summary="V2-获取订单详情",
|
|
|
* description="获取订单详情",
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Parameter(name="id", in="path", @OA\Schema(type="integer"), required=true, description="id"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="获取订单详情"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
|
|
|
public function getOrder($id, $ajax = true)
|
|
|
{
|
|
|
$model = $this->_getOrderModel();
|
|
|
$order = $model->with([
|
|
|
"orderItems" => function ($query) {
|
|
|
$query->orderBy("service_date", "desc");
|
|
|
},
|
|
|
"recharges" => function ($query) {
|
|
|
$query->withCount("refunds");
|
|
|
},
|
|
|
"refunds"
|
|
|
])->find($id);
|
|
|
|
|
|
$order = $order->refreshTotal();
|
|
|
$order->balance = $order->customer->balance;
|
|
|
$paramedic_items = $order->orderItems->groupBy("paramedic_id");
|
|
|
$group_by_paramedic = [];
|
|
|
foreach ($paramedic_items as $k => $items) {
|
|
|
$items = $items->sortBy("id");
|
|
|
$paramedic = Paramedic::withTrashed()->find($k);
|
|
|
$group_by_paramedic[] = [
|
|
|
"paramedic_id" => $k,
|
|
|
"paramedic_name" => $paramedic->name,
|
|
|
"days" => $items->count(),
|
|
|
"from_date" => $items->first()->service_date,
|
|
|
"to_date" => $items->last()->service_date,
|
|
|
];
|
|
|
}
|
|
|
$order->group_by_paramedic = collect($group_by_paramedic);
|
|
|
if ($ajax === true) {
|
|
|
return response()->json($order->toArray());
|
|
|
}
|
|
|
return $order;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\Get(
|
|
|
* path="/manager/get-order-item/{id}",
|
|
|
* tags={"管理端订单处理"},
|
|
|
* summary="V2-获取子订单详情",
|
|
|
* description="获取子订单详情",
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Parameter(name="id", in="path", @OA\Schema(type="integer"), required=true, description="id"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="获取子订单详情"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
|
|
|
public function getOrderItem($id)
|
|
|
{
|
|
|
$order_item = (new OrderItems())->with([
|
|
|
"paramedic" => function ($query) {
|
|
|
$query
|
|
|
->select("paramedic.id", "paramedic.name", "paramedic.avatar", "paramedic.sex")
|
|
|
->leftJoin("paramedic_level", "paramedic_level.id", "=", "paramedic.paramedic_level_id")
|
|
|
->addSelect("paramedic_level.name as paramedic_level_name");
|
|
|
},
|
|
|
"bed" => function ($query) {
|
|
|
$query->select("bed.id", "bed.name", "bed.room_id", "bed.area_id", "bed.building_id")
|
|
|
->leftJoin("building", "building.id", "=", "bed.building_id")
|
|
|
->leftJoin("area", "area.id", "=", "bed.area_id")
|
|
|
->leftJoin("room", "room.id", "=", "bed.room_id")
|
|
|
->addSelect("room.name as room_name", "area.name as area_name", "building.name as building_name");
|
|
|
}
|
|
|
])->find($id);
|
|
|
|
|
|
return response()->json($order_item->toArray());
|
|
|
}
|
|
|
|
|
|
public function _getOrderModel()
|
|
|
{
|
|
|
$model = $order = (new Orders())
|
|
|
->select(
|
|
|
"orders.id",
|
|
|
"orders.serial",
|
|
|
"orders.customer_id",
|
|
|
"orders.manager_id",
|
|
|
"orders.bed_id",
|
|
|
"orders.patient_id",
|
|
|
"orders.project_id",
|
|
|
"orders.product_id",
|
|
|
"orders.product_item_id",
|
|
|
"orders.product_paramedic_level_id",
|
|
|
"orders.from_date",
|
|
|
"orders.to_date",
|
|
|
"orders.status",
|
|
|
"orders.total",
|
|
|
"orders.paid_total",
|
|
|
"orders.contact",
|
|
|
"orders.mobile",
|
|
|
"orders.paramedic_id",
|
|
|
"orders.price",
|
|
|
"orders.factors",
|
|
|
"orders.patient_quantity",
|
|
|
"orders.created_at"
|
|
|
)
|
|
|
->with([
|
|
|
"productItem" => function ($query) {
|
|
|
$query->select("id", "name");
|
|
|
},
|
|
|
"orderAgreements" => function ($query) {
|
|
|
$query->with('paramedicSign', 'customerSign', 'companySign', 'file')->orderBy("id", "desc");
|
|
|
},
|
|
|
"paramedicLevel" => function ($query) {
|
|
|
$query->select("paramedic_level.id", "paramedic_level.name");
|
|
|
},
|
|
|
"project" => function ($query) {
|
|
|
$query->select("id", "name");
|
|
|
},
|
|
|
"bed" => function ($query) {
|
|
|
$query->select("bed.id", "bed.name", "bed.building_id", "bed.area_id")
|
|
|
->leftJoin("building", "building.id", "=", "bed.building_id")
|
|
|
->leftJoin("area", "area.id", "=", "bed.area_id")
|
|
|
->leftJoin("room", "room.id", "=", "bed.room_id")
|
|
|
->addSelect("room.name as room_name", "area.name as area_name", "building.name as building_name");
|
|
|
},
|
|
|
"customer" => function ($query) {
|
|
|
$query->select("id", "name", "balance");
|
|
|
},
|
|
|
"patient" => function ($query) {
|
|
|
$query->select("id", "name", "sex", "age", "mobile");
|
|
|
},
|
|
|
"paramedic" => function ($query) {
|
|
|
$query->select("paramedic.id", "paramedic.name", "paramedic.mobile")
|
|
|
->leftJoin("paramedic_level", "paramedic_level.id", "=", "paramedic.paramedic_level_id")
|
|
|
->addSelect("paramedic_level.name as paramedic_level_name");
|
|
|
}
|
|
|
]);
|
|
|
return $model;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\Get(
|
|
|
* path="/manager/get-project-areas/{project_id}",
|
|
|
* tags={"管理端订单处理"},
|
|
|
* summary="V2-获取医院病区",
|
|
|
* description="获取医院病区",
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Parameter(name="project_id", in="path", @OA\Schema(type="integer"), required=true, description="project id"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="获取医院床位"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
|
|
|
public function getProjectAreas($project_id)
|
|
|
{
|
|
|
$areas = (new Area())
|
|
|
->where("area.project_id", $project_id)
|
|
|
->select("area.id", "area.name", "area.building_id")
|
|
|
->leftJoin("building", "building.id", "=", "area.building_id")
|
|
|
->addSelect("building.name as building_name")
|
|
|
// ->orderBy("building_name")
|
|
|
->orderBy("area.myindex")
|
|
|
//->orderBy("area.name")
|
|
|
->get();
|
|
|
return response()->json($areas->toArray());
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\Get(
|
|
|
* path="/manager/get-area-beds/{area_id}",
|
|
|
* tags={"管理端订单处理"},
|
|
|
* summary="V2-根据病区获取病床",
|
|
|
* description="根据病区获取病床",
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Parameter(name="area_id", in="path", @OA\Schema(type="integer"), required=true, description="area id"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="根据病区获取病床"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
|
|
|
public function getAreaBeds($area_id)
|
|
|
{
|
|
|
$beds = (new Bed())
|
|
|
->where("bed.area_id", $area_id)
|
|
|
->select("bed.id", "bed.name", "bed.area_id", "bed.room_id")
|
|
|
->leftJoin("room", "room.id", "=", "bed.room_id")
|
|
|
->addSelect("room.name as room_name")
|
|
|
->orderBy("bed.myindex")
|
|
|
->get();
|
|
|
|
|
|
return response()->json($beds->toArray());
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\Get(
|
|
|
* path="/manager/get-available-paramedics",
|
|
|
* tags={"管理端订单处理"},
|
|
|
* summary="V2-获取可用护工列表(已基本准确,需进一步打磨)",
|
|
|
* description="获取可用护工列表",
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Parameter(name="bed_id", in="query", @OA\Schema(type="integer"), required=true, description="床位ID"),
|
|
|
* @OA\Parameter(name="sex", in="query", @OA\Schema(type="string"), required=true, description="性别:[男/女]"),
|
|
|
* @OA\Parameter(name="start_date", in="query", @OA\Schema(type="string"), required=false, description="日期,默认为当天"),
|
|
|
* @OA\Parameter(name="factors", in="query", @OA\Schema(type="object"), required=true, description="价格因子选择,[{id:1,factor_item_id:1},{...}],如果为空数组请传[]"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="获取可用护工列表"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
|
|
|
public function getAvailableParamedics(Request $request)
|
|
|
{
|
|
|
$paramedics = (new Orders())->getAvailableParamedics();
|
|
|
return response()->json($paramedics);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\POST(
|
|
|
* path="/manager/create-patient",
|
|
|
* tags={"管理端订单处理"},
|
|
|
* summary="V2-创建被护理人",
|
|
|
* description="创建被护理人",
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Parameter(name="name", in="query", @OA\Schema(type="string"), required=true, description="姓名"),
|
|
|
* @OA\Parameter(name="sex", in="query", @OA\Schema(type="string"), required=true, description="性别:[男/女]"),
|
|
|
* @OA\Parameter(name="age", in="query", @OA\Schema(type="integer"), required=true, description="年龄,只需填写入院时的年龄"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="创建被护理人"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
public function createPatient()
|
|
|
{
|
|
|
$data = [
|
|
|
"name" => request()->name,
|
|
|
"sex" => request()->sex,
|
|
|
"age" => request()->age,
|
|
|
"mobile" => request()->mobile
|
|
|
];
|
|
|
|
|
|
$vo = (new Patient())->create($data);
|
|
|
return response()->json($vo);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\POST(
|
|
|
* path="/manager/create-order",
|
|
|
* tags={"管理端订单处理"},
|
|
|
* summary="V2-创建订单",
|
|
|
* description="创建订单",
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Parameter(name="product_id", in="query", @OA\Schema(type="integer"), required=true, description="产品id"),
|
|
|
* @OA\Parameter(name="product_item_id", in="query", @OA\Schema(type="integer"), required=true, description="产品型号id"),
|
|
|
* @OA\Parameter(name="product_paramedic_level_id", in="query", @OA\Schema(type="integer"), required=true, description="产品-护工等级id"),
|
|
|
* @OA\Parameter(name="factors", in="query", @OA\Schema(type="object"), required=true, description="价格因子选择,[{id:1,factor_item_id:1},{...}],如果为空数组请传[]"),
|
|
|
* @OA\Parameter(name="bed_id", in="query", @OA\Schema(type="integer"), required=true, description="床位id"),
|
|
|
* @OA\Parameter(name="paramedic_id", in="query", @OA\Schema(type="integer"), required=false, description="护工id"),
|
|
|
* @OA\Parameter(name="patient_name", in="query", @OA\Schema(type="string"), required=true, description="被护理人姓名"),
|
|
|
* @OA\Parameter(name="patient_mobile", in="query", @OA\Schema(type="string"), required=true, description="被护理人电话"),
|
|
|
* @OA\Parameter(name="patient_sex", in="query", @OA\Schema(type="string"), required=true, description="被护理人性别:男,女"),
|
|
|
* @OA\Parameter(name="patient_age", in="query", @OA\Schema(type="string"), required=true, description="被护理人年龄"),
|
|
|
* @OA\Parameter(name="contact", in="query", @OA\Schema(type="string"), required=false, description="联系人"),
|
|
|
* @OA\Parameter(name="mobile", in="query", @OA\Schema(type="string"), required=false, description="联系人电话"),
|
|
|
* @OA\Parameter(name="from_date", in="query", @OA\Schema(type="string"), required=true, description="开始日期"),
|
|
|
* @OA\Parameter(name="to_date", in="query", @OA\Schema(type="string"), required=true, description="结束日期"),
|
|
|
* @OA\Parameter(name="price", in="query", @OA\Schema(type="number"), required=true, description="协商价格"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="创建订单"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
public function createOrder()
|
|
|
{
|
|
|
DB::beginTransaction();
|
|
|
try {
|
|
|
$mobile = request()->mobile ?? request()->patient_mobile;
|
|
|
$customer = (new Customer())->firstOrCreate([
|
|
|
"mobile" => $mobile
|
|
|
]);
|
|
|
|
|
|
$has_orders = Orders::where("customer_id", $customer->id)->whereIn("status", [Orders::STATUS_UNCONFIRMED, Orders::STATUS_UNASSIGNED, Orders::STATUS_ONGOING])->count();
|
|
|
if ($has_orders) {
|
|
|
return response()->json([
|
|
|
"errorcode" => "101",
|
|
|
"errormsg" => "客户名下有即将开始或正在进行中的订单,暂不可以再次下单"
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
$product = (new Product())->find(request()->product_id);
|
|
|
$product_paramedic_level = (new ProductParamedicLevel())->find(request()->product_paramedic_level_id);
|
|
|
$product_item = (new ProductItems())->find(request()->product_item_id);
|
|
|
$price = $product_item->price + $product_paramedic_level->price;
|
|
|
|
|
|
$factors = (new Orders())->requestFactorsToOrderFactors();
|
|
|
$price += collect($factors)->sum("price");
|
|
|
if (request()->price < $price) {
|
|
|
return response()->json([
|
|
|
"errorcode" => "102",
|
|
|
"errormsg" => "协商价格不能低于系统指导价"
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
$patient = (new Patient())->firstOrCreate([
|
|
|
"customer_id" => $customer->id,
|
|
|
"name" => request()->patient_name
|
|
|
]);
|
|
|
$patient->update([
|
|
|
"age" => request()->patient_age,
|
|
|
"sex" => request()->patient_sex,
|
|
|
"mobile" => request()->patient_mobile,
|
|
|
]);
|
|
|
|
|
|
$order = (new Orders())->create([
|
|
|
"customer_id" => $customer->id,
|
|
|
"project_id" => $product->id,
|
|
|
"product_id" => request()->product_id,
|
|
|
"patient_id" => $patient->id,
|
|
|
"contact" => request()->contact ?? request()->patient_name,
|
|
|
"mobile" => request()->mobile ?? request()->patient_mobile,
|
|
|
"from_date" => request()->from_date,
|
|
|
"to_date" => request()->to_date,
|
|
|
"product_item_id" => request()->product_item_id,
|
|
|
"product_paramedic_level_id" => request()->product_paramedic_level_id,
|
|
|
"bed_id" => request()->bed_id,
|
|
|
"paramedic_id" => request()->paramedic_id,
|
|
|
"price" => request()->price,
|
|
|
"factors" => json_encode($factors),
|
|
|
"status" => request()->paramedic_id ? Orders::STATUS_ONGOING : Orders::STATUS_UNASSIGNED,
|
|
|
"manager_id" => $this->manager->id
|
|
|
]);
|
|
|
|
|
|
$order->getSerial();
|
|
|
if (request()->paramedic_id) {
|
|
|
event(new OrderAssigned($order));
|
|
|
}
|
|
|
DB::commit();
|
|
|
$order = $this->getOrder($order->id, false);
|
|
|
if (request()->paramedic_id) {
|
|
|
$order = (new AttachAffectedOrders)($order);
|
|
|
}
|
|
|
return response()->json($order->toArray());
|
|
|
} catch (\Exception $exception) {
|
|
|
DB::rollBack();
|
|
|
return response()->json([
|
|
|
"errorcode" => $exception->getCode(),
|
|
|
"errormsg" => $exception->getMessage()
|
|
|
]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\POST(
|
|
|
* path="/manager/update-order/{id}",
|
|
|
* tags={"管理端订单处理"},
|
|
|
* summary="V2-订单修改(静态修改不影响当前所有子订单)",
|
|
|
* description="订单修改",
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Parameter(name="product_id", in="query", @OA\Schema(type="integer"), required=true, description="产品id"),
|
|
|
* @OA\Parameter(name="product_item_id", in="query", @OA\Schema(type="integer"), required=true, description="产品型号id"),
|
|
|
* @OA\Parameter(name="product_paramedic_level_id", in="query", @OA\Schema(type="integer"), required=true, description="产品-护工等级id"),
|
|
|
* @OA\Parameter(name="factors", in="query", @OA\Schema(type="object"), required=true, description="价格因子选择,[{id:1,factor_item_id:1},{...}],如果为空数组请传[]"),
|
|
|
* @OA\Parameter(name="bed_id", in="query", @OA\Schema(type="integer"), required=true, description="床位id"),
|
|
|
* @OA\Parameter(name="paramedic_id", in="query", @OA\Schema(type="integer"), required=false, description="护工id"),
|
|
|
* @OA\Parameter(name="patient_name", in="query", @OA\Schema(type="string"), required=true, description="被护理人姓名"),
|
|
|
* @OA\Parameter(name="patient_mobile", in="query", @OA\Schema(type="string"), required=true, description="被护理人电话"),
|
|
|
* @OA\Parameter(name="patient_sex", in="query", @OA\Schema(type="string"), required=true, description="被护理人性别:男,女"),
|
|
|
* @OA\Parameter(name="patient_age", in="query", @OA\Schema(type="string"), required=true, description="被护理人年龄"),
|
|
|
* @OA\Parameter(name="contact", in="query", @OA\Schema(type="string"), required=false, description="联系人"),
|
|
|
* @OA\Parameter(name="mobile", in="query", @OA\Schema(type="string"), required=false, description="联系人电话"),
|
|
|
* @OA\Parameter(name="from_date", in="query", @OA\Schema(type="string"), required=true, description="开始日期"),
|
|
|
* @OA\Parameter(name="to_date", in="query", @OA\Schema(type="string"), required=true, description="结束日期"),
|
|
|
* @OA\Parameter(name="price", in="query", @OA\Schema(type="number"), required=true, description="协商价格"),
|
|
|
* @OA\Parameter(name="available_day", in="query", @OA\Schema(type="number"), required=true, description="生效日期,仅当值为today表示同步更新当日子订单价格,为其他值表示次日起生效"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="订单修改",
|
|
|
* content={
|
|
|
* @OA\MediaType(
|
|
|
* mediaType="application/json",
|
|
|
* @OA\Schema(
|
|
|
* @OA\Property(
|
|
|
* property="errorcode",
|
|
|
* type="integer",
|
|
|
* description="错误码;仅在发生错误时发送"
|
|
|
* ),
|
|
|
* @OA\Property(
|
|
|
* property="errormsg",
|
|
|
* type="string",
|
|
|
* description="返回消息;有errorcode时为错误内容,无errorcode时为提示内容"
|
|
|
* ),
|
|
|
* @OA\Property(
|
|
|
* property="order.*",
|
|
|
* type="string",
|
|
|
* description="订单实体"
|
|
|
* ),
|
|
|
* @OA\Property(
|
|
|
* property="affected_orders",
|
|
|
* type="array",
|
|
|
* @OA\Items(),
|
|
|
* description="特别说明:影响到的订单,如果无此字段或数组为空表示未发生订单影响。影响到的订单实体数组,实体中的change字段(many_to_one或one_to_many)表示影响的方向"
|
|
|
* )
|
|
|
* )
|
|
|
* )
|
|
|
* }
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
public function updateOrder($id)
|
|
|
{
|
|
|
DB::beginTransaction();
|
|
|
try {
|
|
|
$order = Orders::with(["customer", "patient", "product", "productItem", "productParamedicLevel"])->find($id);
|
|
|
|
|
|
$product_paramedic_level = request()->has("product_paramedic_level_id") ? (new ProductParamedicLevel())->find(request()->product_paramedic_level_id) : $order->productParamedicLevel;
|
|
|
$product_item = request()->has("product_item_id") ? (new ProductItems())->find(request()->product_item_id) : $order->productItem;
|
|
|
$price = $product_item->price + $product_paramedic_level->price;
|
|
|
|
|
|
if (request()->has("factors")) {
|
|
|
$factors = (new Orders())->requestFactorsToOrderFactors();
|
|
|
} else {
|
|
|
$factors = json_decode($order->factors);
|
|
|
}
|
|
|
|
|
|
$price += collect($factors)->sum("price");
|
|
|
if (request()->has("price") && request()->price < $price) {
|
|
|
return response()->json([
|
|
|
"errorcode" => "102",
|
|
|
"errormsg" => "协商价格不能低于系统指导价"
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
//更新被陪护人
|
|
|
if (request()->has("patient_name", "patient_mobile", "patient_sex", "patient_age")) {
|
|
|
$order->patient->update([
|
|
|
"name" => request()->patient_name,
|
|
|
"age" => request()->patient_age,
|
|
|
"sex" => request()->patient_sex,
|
|
|
"mobile" => request()->patient_mobile,
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
//更新订单基本信息
|
|
|
$from_paramedic = $order->paramedic_id;
|
|
|
$update = (new Orders())->filterRequestColumns(request(), ["id"]);
|
|
|
if (request()->has("contact", "patient_name") && !request()->contact) {
|
|
|
$update["contact"] = request()->patient_name;
|
|
|
}
|
|
|
if (request()->has("mobile", "patient_mobile") && !request()->mobile) {
|
|
|
$update["mobile"] = request()->patient_mobile;
|
|
|
}
|
|
|
if (request()->has("factors")) {
|
|
|
$update["factors"] = json_encode($factors);
|
|
|
}
|
|
|
$order->update($update);
|
|
|
|
|
|
//正在进行中当天的子订单修改
|
|
|
if ($order->isOngoing() && request()->available_day == "today") {
|
|
|
$res = (new OrderItems())->updateTodayItem($order->id);
|
|
|
if (!$res["status"]) {
|
|
|
return response()->json([
|
|
|
"errorcode" => "103",
|
|
|
"errormsg" => $res["msg"]
|
|
|
]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//如果原本的护工id为空且新提交了护工id,视同为派单
|
|
|
if ($order->isPending() && request()->paramedic_id) {
|
|
|
$order->update([
|
|
|
"paramedic_id" => request()->paramedic_id,
|
|
|
"status" => Orders::STATUS_ONGOING
|
|
|
]);
|
|
|
event(new OrderAssigned($order));
|
|
|
}
|
|
|
|
|
|
$order = (new AttachAffectedOrders)($order, $from_paramedic);
|
|
|
DB::commit();
|
|
|
return response()->json($order->toArray());
|
|
|
} catch (\Exception $exception) {
|
|
|
DB::rollBack();
|
|
|
return response()->json([
|
|
|
"errorcode" => $exception->getCode(),
|
|
|
"errormsg" => $exception->getMessage()
|
|
|
]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\POST(
|
|
|
* path="/manager/update-order-items",
|
|
|
* tags={"管理端订单处理"},
|
|
|
* summary="V2-子订单修改(覆盖单条修改),20230618更新:对早于过上月的价格锁定",
|
|
|
* description="子订单修改",
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Parameter(name="ids", in="query", @OA\Schema(type="integer"), required=true, description="子订单id,可传单个id或数组"),
|
|
|
* @OA\Parameter(name="bed_id", in="query", @OA\Schema(type="integer"), required=false, description="床位id"),
|
|
|
* @OA\Parameter(name="paramedic_id", in="query", @OA\Schema(type="integer"), required=false, description="护工id"),
|
|
|
* @OA\Parameter(name="price", in="query", @OA\Schema(type="integer"), required=false, description="价格"),
|
|
|
* @OA\Parameter(name="skip_warnings", in="query", @OA\Schema(type="integer"), required=false, description="跳过警示项目"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="子订单修改",
|
|
|
* content={
|
|
|
* @OA\MediaType(
|
|
|
* mediaType="application/json",
|
|
|
* @OA\Schema(
|
|
|
* @OA\Property(
|
|
|
* property="errorcode",
|
|
|
* type="integer",
|
|
|
* description="错误码;仅在发生错误时发送"
|
|
|
* ),
|
|
|
* @OA\Property(
|
|
|
* property="errormsg",
|
|
|
* type="string",
|
|
|
* description="返回消息;有errorcode时为错误内容,无errorcode时为提示内容"
|
|
|
* ),
|
|
|
* @OA\Property(
|
|
|
* property="has_warnings",
|
|
|
* type="boolean",
|
|
|
* description="是否有警告内容;仅在有警告内容且无错误代码的情况下发送,此时读取errormsg为警告内容"
|
|
|
* ),
|
|
|
* @OA\Property(
|
|
|
* property="updated_items",
|
|
|
* type="integer",
|
|
|
* description="更新的子订单总数;仅在成功的情况下发送"
|
|
|
* ),
|
|
|
* @OA\Property(
|
|
|
* property="updated_paid_items",
|
|
|
* type="integer",
|
|
|
* description="产生了价格波动的子订单总数,连锁效应为每条价格波动会新增一条财务记录,并影响客户的余额;仅在成功的情况下发送"
|
|
|
* ),
|
|
|
* example={
|
|
|
* "errorcode": "105",
|
|
|
* "errormsg": "价格补差100超过了客户余额90,请先充值",
|
|
|
* "has_warnings": 1,
|
|
|
* "updated_items": 10,
|
|
|
* "updated_paid_items": 3
|
|
|
* }
|
|
|
* )
|
|
|
* )
|
|
|
* }
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
public function updateOrderItems(Request $request)
|
|
|
{
|
|
|
$ids = explode(",", $request->ids);
|
|
|
$order_items = (new OrderItems())->whereHas("order")->whereIn("id", $ids)->with("customer")->get();
|
|
|
if (!$order_items->count()) {
|
|
|
return response()->json([
|
|
|
"errorcode" => "105",
|
|
|
"errormsg" => "没有获取到子订单"
|
|
|
]);
|
|
|
}
|
|
|
$customer = $order_items->first()->customer;
|
|
|
$price_changed_paid_items = $order_items->filter(function ($item) use ($request) {
|
|
|
return $request->has("price") && $item->paid_at && ($request->price != $item->total);
|
|
|
});
|
|
|
|
|
|
$price_changed_last_month_paid_items = $price_changed_paid_items->filter(function ($item) {
|
|
|
return date("Ym", strtotime($item->paid_at)) != date("Ym");
|
|
|
});
|
|
|
|
|
|
$total_increased = $price_changed_paid_items->count() * $request->price - $price_changed_paid_items->sum("total");
|
|
|
|
|
|
$warnings = [];
|
|
|
$errors = [];
|
|
|
|
|
|
if ($price_changed_last_month_paid_items->count()) {
|
|
|
$errors[] = "有" . $price_changed_last_month_paid_items->count() . "天往月扣款的子订单已锁定价格,不可修改";
|
|
|
}
|
|
|
|
|
|
$manager = $this->guard()->user();
|
|
|
// if (!$manager->no_lock_ability) { //2023年8月份有开通一个功能,让具有权限的人可以修改往月的已扣款订单,后发现有问题,现在改为只可以对当月或上月已扣款订单进行修改
|
|
|
foreach ($order_items as $_item) {
|
|
|
if ($_item->paid_at && $request->price && $_item->total != $request->price && date("Ym", strtotime($_item->service_date)) < date("Ym", strtotime("-1 month", time()))) {
|
|
|
$errors[] = "子订单{$_item->service_date}价格已锁定";
|
|
|
}
|
|
|
}
|
|
|
// }
|
|
|
|
|
|
if ($total_increased > $customer->balance) {
|
|
|
$errors[] = "价格补差{$total_increased}超过了客户余额{$customer->balance},请先充值";
|
|
|
}
|
|
|
|
|
|
//todo:价格低于指导价的提示
|
|
|
if (count($errors)) {
|
|
|
return response()->json([
|
|
|
"errorcode" => "105",
|
|
|
"errormsg" => implode(";", $errors)
|
|
|
]);
|
|
|
}
|
|
|
if (count($warnings) && !$request->skip_warnings) {
|
|
|
return response()->json([
|
|
|
"has_warnings" => true,
|
|
|
"errormsg" => implode(";", $warnings)
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
DB::beginTransaction();
|
|
|
try {
|
|
|
//根据已付款的价格异动子订单循环添加余额平衡表记录,并随时更新客户余额值,执行完毕后保存客户余额更新
|
|
|
foreach ($price_changed_paid_items as $price_changed_paid_item) {
|
|
|
$total_offset = $price_changed_paid_item->total - $request->price;
|
|
|
$customer->balance = $customer->balance + $total_offset;
|
|
|
(new Balance())->create([
|
|
|
"customer_id" => $customer->id,
|
|
|
"order_id" => $price_changed_paid_item->order_id,
|
|
|
"belongs_type" => get_class($price_changed_paid_item),
|
|
|
"belongs_id" => $price_changed_paid_item->id,
|
|
|
"money" => $total_offset,
|
|
|
"balance" => $customer->balance
|
|
|
]);
|
|
|
}
|
|
|
$customer->save();
|
|
|
|
|
|
//循环更新所有子订单
|
|
|
$update = [];
|
|
|
if ($request->has("bed_id")) {
|
|
|
$update["bed_id"] = $request->bed_id;
|
|
|
}
|
|
|
if ($request->has("paramedic_id")) {
|
|
|
$update["paramedic_id"] = $request->paramedic_id;
|
|
|
}
|
|
|
if ($request->has("price")) {
|
|
|
$update["total"] = $request->price;
|
|
|
}
|
|
|
foreach ($order_items as $order_item) {
|
|
|
$order_item->update($update);
|
|
|
}
|
|
|
|
|
|
DB::commit();
|
|
|
return response()->json([
|
|
|
"updated_items" => count($order_items),
|
|
|
"updated_paid_items" => count($price_changed_paid_items)
|
|
|
]);
|
|
|
} catch (\Exception $exception) {
|
|
|
DB::rollBack();
|
|
|
return response()->json([
|
|
|
"errorcode" => $exception->getCode(),
|
|
|
"errormsg" => $exception->getMessage()
|
|
|
]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\POST(
|
|
|
* path="/manager/checkout-order-items/{order_id}",
|
|
|
* tags={"管理端订单处理"},
|
|
|
* summary="V2-中途结算(即只依次结算子订单,并不结束订单,只需余额刚好)",
|
|
|
* description="交互流程如下:初次请求带上just_check参数,将返回to_recharge_total值;如果to_recharge_total大于0表示需要充值,充值完成之后,去除just_check参数再次提交;如果to_recharge_total <= 0,直接去除just_check参数再次提交",
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Parameter(name="order_id", in="path", @OA\Schema(type="integer"), required=true, description="订单id"),
|
|
|
* @OA\Parameter(name="to_date", in="query", @OA\Schema(type="date"), required=true, description="结算到的日子"),
|
|
|
* @OA\Parameter(name="just_check", in="query", @OA\Schema(type="boolean"), required=false, description="是否只是check一下要多少钱"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="中途结算",
|
|
|
* content={
|
|
|
* @OA\MediaType(
|
|
|
* mediaType="application/json",
|
|
|
* @OA\Schema(
|
|
|
* @OA\Property(
|
|
|
* property="errorcode",
|
|
|
* type="integer",
|
|
|
* description="错误码;仅在发生错误时发送"
|
|
|
* ),
|
|
|
* @OA\Property(
|
|
|
* property="errormsg",
|
|
|
* type="string",
|
|
|
* description="返回消息;有errorcode时为错误内容,无errorcode时为提示内容"
|
|
|
* ),
|
|
|
* @OA\Property(
|
|
|
* property="prepay_total",
|
|
|
* type="decimal",
|
|
|
* description="总计需要预扣的金额,入参just_check为1时just_check为0但是客户余额不足时返回"
|
|
|
* ),
|
|
|
* @OA\Property(
|
|
|
* property="customer_balance",
|
|
|
* type="decimal",
|
|
|
* description="客户余额,入参just_check为1时just_check为0但是客户余额不足时返回"
|
|
|
* ),
|
|
|
* @OA\Property(
|
|
|
* property="to_recharge_total",
|
|
|
* type="decimal",
|
|
|
* description="需要充值的金额,入参just_check为1时(此时to_recharge_total值如果大于0则需要充值)或just_check为0但是客户余额不足时(此时to_recharge_total值一定大于0)返回"
|
|
|
* ),
|
|
|
* @OA\Property(
|
|
|
* property="updated_items",
|
|
|
* type="integer",
|
|
|
* description="结算的子订单总数;仅在成功的情况下发送"
|
|
|
* ),
|
|
|
* example={
|
|
|
* "errorcode": "30003",
|
|
|
* "errormsg": "截止到中途结算日,没有需要结算的子订单,如需预充值请发起收款操作",
|
|
|
* "prepay_total": 1000,
|
|
|
* "customer_balance": 10,
|
|
|
* "to_recharge_total": 990,
|
|
|
* "checkout_items": 10
|
|
|
* }
|
|
|
* )
|
|
|
* )
|
|
|
* }
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
public function checkoutOrderItems($order_id, Request $request)
|
|
|
{
|
|
|
$order = Orders::with("customer")->find($order_id);
|
|
|
if ($order->status != Orders::STATUS_ONGOING) {
|
|
|
return response()->json([
|
|
|
"errorcode" => 30000,
|
|
|
"errormsg" => "订单状态不匹配"
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
$order_items = OrderItems::where("order_id", $order_id)->whereRaw("DATEDIFF('{$request->to_date}',`service_date`) >= 0")->orderBy("service_date", "asc")->get();
|
|
|
$unpaid_order_items = $order_items->filter(function ($item) {
|
|
|
return $item->total > 0 && !$item->paid_at;
|
|
|
});
|
|
|
|
|
|
if ($order_items->count()) {
|
|
|
$to_generate_days = Carbon::parse($order_items->last()->service_date)->diffInDays($request->to_date, false);
|
|
|
$to_generate_start_date = Carbon::parse($order_items->last()->service_date)->addDay()->toDateString();
|
|
|
} else {
|
|
|
$to_generate_days = Carbon::parse($order->from_date)->diffInDays($request->to_date, false) + 1;
|
|
|
$to_generate_start_date = $order->from_date;
|
|
|
}
|
|
|
|
|
|
$to_generate_days = max(0, $to_generate_days);
|
|
|
for ($i = 0; $i < $to_generate_days; $i++) {
|
|
|
if ($i > 0) {
|
|
|
$service_date = Carbon::parse($to_generate_start_date)->addDays($i)->toDateString();
|
|
|
} else {
|
|
|
$service_date = $to_generate_start_date;
|
|
|
}
|
|
|
if (strtotime($service_date) >= strtotime("+1 month", strtotime(date("Y-m") . "-01"))) {
|
|
|
return response()->json([
|
|
|
"errorcode" => 30003,
|
|
|
"errormsg" => "中途结算最大时限不能超过当月月底"
|
|
|
]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
$prepay_total = $unpaid_order_items->sum("total") + $to_generate_days * $order->price;
|
|
|
$to_recharge_total = $prepay_total - $order->customer->balance;
|
|
|
|
|
|
//如果只是检查一下需要充值金额,直接返回
|
|
|
if ($request->just_check) {
|
|
|
return response()->json([
|
|
|
"prepay_total" => $prepay_total,
|
|
|
"customer_balance" => $order->customer->balance,
|
|
|
"to_recharge_total" => $to_recharge_total
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
//没有需要操作的子订单,无意义
|
|
|
if (!$unpaid_order_items->count() && !$to_generate_days) {
|
|
|
return response()->json([
|
|
|
"errorcode" => 30001,
|
|
|
"errormsg" => "截止到中途结算日,没有需要结算的子订单,如需预充值请发起收款操作"
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
//需要预先充值
|
|
|
if ($to_recharge_total > 0) {
|
|
|
return response()->json([
|
|
|
"errorcode" => 30002,
|
|
|
"errormsg" => "余额不足,请先充值",
|
|
|
"prepay_total" => $prepay_total,
|
|
|
"customer_balance" => $order->customer->balance,
|
|
|
"to_recharge_total" => $to_recharge_total
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
DB::beginTransaction();
|
|
|
try {
|
|
|
foreach ($unpaid_order_items as $order_item) {
|
|
|
//更新子订单支付状态
|
|
|
$order_item->update(["paid_at" => date("Y-m-d H:i:s")]);
|
|
|
|
|
|
//更新客户余额(暂不保存,最后统一保存)
|
|
|
$order->customer->balance = $order->customer->balance - $order_item->total;
|
|
|
|
|
|
//创建收款记录
|
|
|
(new Balance())->create([
|
|
|
"customer_id" => $order->customer->id,
|
|
|
"order_id" => $order->id,
|
|
|
"belongs_type" => get_class($order_item),
|
|
|
"belongs_id" => $order_item->id,
|
|
|
"money" => -$order_item->total,
|
|
|
"balance" => $order->customer->balance
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
for ($i = 0; $i < $to_generate_days; $i++) {
|
|
|
if ($i > 0) {
|
|
|
$service_date = Carbon::parse($to_generate_start_date)->addDays($i)->toDateString();
|
|
|
} else {
|
|
|
$service_date = $to_generate_start_date;
|
|
|
}
|
|
|
if (strtotime($service_date) >= strtotime("+1 month", strtotime(date("Y-m") . "-01"))) {
|
|
|
return response()->json([
|
|
|
"errorcode" => 30003,
|
|
|
"errormsg" => "中途结算最大时限不能超过当月月底,已收的多余款项将于下月使用"
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
$order_item = (new OrderItems())->createItem($order->id, $service_date);
|
|
|
|
|
|
//更新子订单支付状态
|
|
|
$order_item->update(["paid_at" => date("Y-m-d H:i:s")]);
|
|
|
|
|
|
//更新客户余额(暂不保存,最后统一保存)
|
|
|
$order->customer->balance = $order->customer->balance - $order_item->total;
|
|
|
|
|
|
//创建收款记录
|
|
|
(new Balance())->create([
|
|
|
"customer_id" => $order->customer->id,
|
|
|
"order_id" => $order->id,
|
|
|
"belongs_type" => get_class($order_item),
|
|
|
"belongs_id" => $order_item->id,
|
|
|
"money" => -$order_item->total,
|
|
|
"balance" => $order->customer->balance
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
$order->customer->save();
|
|
|
DB::commit();
|
|
|
return response()->json([
|
|
|
"checkout_items" => count($unpaid_order_items)
|
|
|
]);
|
|
|
} catch (\Exception $exception) {
|
|
|
DB::rollBack();
|
|
|
return response()->json([
|
|
|
"errorcode" => $exception->getCode(),
|
|
|
"errormsg" => $exception->getMessage()
|
|
|
]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\POST(
|
|
|
* path="/manager/checkout-order/{id}",
|
|
|
* tags={"管理端订单处理"},
|
|
|
* summary="V2-订单结算",
|
|
|
* description="交互流程如下:初次请求带上just_check参数,将返回to_recharge_total和to_refund_total值;仅在to_recharge_total和to_refund_total都为0的情况下才可以结算成功;如果to_recharge_total大于0表示需要充值,充值完成之后,剔除just_check参数再次提交;如果to_refund_total大于0表示需要退款,根据返回的退款方式操作后,剔除just_check参数再次提交",
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Parameter(name="id", in="path", @OA\Schema(type="integer"), required=true, description="订单id"),
|
|
|
* @OA\Parameter(name="to_date", in="query", @OA\Schema(type="date"), required=true, description="结算到的日子"),
|
|
|
* @OA\Parameter(name="just_check", in="query", @OA\Schema(type="boolean"), required=false, description="是否只是check一下要多少钱"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="订单结算",
|
|
|
* content={
|
|
|
* @OA\MediaType(
|
|
|
* mediaType="application/json",
|
|
|
* @OA\Schema(
|
|
|
* @OA\Property(
|
|
|
* property="errorcode",
|
|
|
* type="integer",
|
|
|
* description="错误码;仅在发生错误时发送"
|
|
|
* ),
|
|
|
* @OA\Property(
|
|
|
* property="errormsg",
|
|
|
* type="string",
|
|
|
* description="返回消息;有errorcode时为错误内容,无errorcode时为提示内容"
|
|
|
* ),
|
|
|
* @OA\Property(
|
|
|
* property="prepay_total",
|
|
|
* type="decimal",
|
|
|
* description="总计需要扣除的金额,入参just_check为1时just_check为0但是客户余额不足时返回"
|
|
|
* ),
|
|
|
* @OA\Property(
|
|
|
* property="customer_balance",
|
|
|
* type="decimal",
|
|
|
* description="客户余额,入参just_check为1时just_check为0但是客户余额不足时返回"
|
|
|
* ),
|
|
|
* @OA\Property(
|
|
|
* property="to_recharge_total",
|
|
|
* type="decimal",
|
|
|
* description="需要充值的金额"
|
|
|
* ),
|
|
|
* @OA\Property(
|
|
|
* property="to_refund_total",
|
|
|
* type="decimal",
|
|
|
* description="需要退款的金额"
|
|
|
* ),
|
|
|
* @OA\Property(
|
|
|
* property="refund_payment",
|
|
|
* type="string",
|
|
|
* description="退款方式"
|
|
|
* ),
|
|
|
* @OA\Property(
|
|
|
* property="refund_recharge_id",
|
|
|
* type="integer",
|
|
|
* description="在线退款原路返回对应的在线充值id"
|
|
|
* ),
|
|
|
* @OA\Property(
|
|
|
* property="refund_recharge_transaction_id",
|
|
|
* type="integer",
|
|
|
* description="在线退款原路返回所对应的在线充值记录的支付平台交易编号"
|
|
|
* ),
|
|
|
* @OA\Property(
|
|
|
* property="checkout_order_id",
|
|
|
* type="integer",
|
|
|
* description="结算成功返回订单id;仅在成功的情况下发送"
|
|
|
* ),
|
|
|
* example={
|
|
|
* "errorcode": "30006",
|
|
|
* "errormsg": "结算日不能早于最后一个已服务且扣款的子订单",
|
|
|
* "prepay_total": 100,
|
|
|
* "customer_balance": 200,
|
|
|
* "to_recharge_total": 0,
|
|
|
* "to_refund_total": 100,
|
|
|
* "refund_recharge_id": 1123,
|
|
|
* "refund_recharge_serial": 1123,
|
|
|
* "checkout_order_id": 777
|
|
|
* }
|
|
|
* )
|
|
|
* )
|
|
|
* }
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
public function checkoutOrder($id, Request $request)
|
|
|
{
|
|
|
$order = Orders::with("customer")->find($id);
|
|
|
if ($order->status != Orders::STATUS_ONGOING) {
|
|
|
return response()->json([
|
|
|
"errorcode" => 30000,
|
|
|
"errormsg" => "订单状态不匹配"
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
$order_items = OrderItems::where("order_id", $id)
|
|
|
->orderBy("service_date", "asc")
|
|
|
->get();
|
|
|
$last_paid_order_item = $order_items->filter(function ($item) {
|
|
|
return $item->total > 0 && $item->paid_at;
|
|
|
})->last();
|
|
|
|
|
|
//结算日早于最后一个已扣款的日期,退回先处理好子订单再结算
|
|
|
if ($last_paid_order_item) {
|
|
|
if (Carbon::parse($request->to_date)->diffInDays($last_paid_order_item->service_date, false) > 0) {
|
|
|
return response()->json([
|
|
|
"errorcode" => 30006,
|
|
|
"errormsg" => "结算日不能早于最后一个已服务且扣款的子订单{$last_paid_order_item->service_date}:$request->to_date"
|
|
|
]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//计算结算数据
|
|
|
$unpaid_order_items = $order_items->filter(function ($item) {
|
|
|
return $item->total > 0 && !$item->paid_at;
|
|
|
});
|
|
|
if ($order_items->count()) {
|
|
|
$to_generate_days = Carbon::parse($order_items->last()->service_date)->diffInDays($request->to_date, false);
|
|
|
$to_generate_start_date = Carbon::parse($order_items->last()->service_date)->addDay()->toDateString();
|
|
|
} else {
|
|
|
$to_generate_days = Carbon::parse($order->from_date)->diffInDays($request->to_date, false) + 1;
|
|
|
$to_generate_start_date = $order->from_date;
|
|
|
}
|
|
|
$to_generate_days = max(0, $to_generate_days);
|
|
|
$prepay_total = $unpaid_order_items->sum("total") + $to_generate_days * $order->price;
|
|
|
$to_recharge_total = $prepay_total - $order->customer->balance;
|
|
|
//通过以下处理后可得出三种情形:1、需要充值;2、需要退款;3、账务平衡可结单
|
|
|
$to_refund_total = max(0, -$to_recharge_total);
|
|
|
$to_recharge_total = max(0, $to_recharge_total);
|
|
|
if ($to_refund_total > 0) {
|
|
|
$recharge_for_online_refund = $order->getOnlineRefundableRecharge($to_refund_total);
|
|
|
} else {
|
|
|
$recharge_for_online_refund = null;
|
|
|
}
|
|
|
|
|
|
//如果只是检查一下需要充值或退款金额,直接返回
|
|
|
if ($request->just_check) {
|
|
|
return response()->json([
|
|
|
"prepay_total" => $prepay_total,
|
|
|
"customer_balance" => $order->customer->balance,
|
|
|
"to_recharge_total" => $to_recharge_total,
|
|
|
"to_refund_total" => $to_refund_total,
|
|
|
"refund_payment" => $recharge_for_online_refund ? $recharge_for_online_refund->payment : "cash",
|
|
|
"refund_recharge_id" => $recharge_for_online_refund ? $recharge_for_online_refund->id : null,
|
|
|
"refund_recharge_transaction_id" => $recharge_for_online_refund ? $recharge_for_online_refund->payment_serial : null
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
//1、需要充值
|
|
|
if ($to_recharge_total > 0) {
|
|
|
return response()->json([
|
|
|
"errorcode" => 30007,
|
|
|
"errormsg" => "余额不足,请先充值",
|
|
|
"prepay_total" => $prepay_total,
|
|
|
"customer_balance" => $order->customer->balance,
|
|
|
"to_recharge_total" => $to_recharge_total
|
|
|
]);
|
|
|
}
|
|
|
//2、需要退款
|
|
|
if ($to_refund_total > 0) {
|
|
|
return response()->json([
|
|
|
"errorcode" => 30008,
|
|
|
"errormsg" => "请先进行退款操作后再结单",
|
|
|
"prepay_total" => $prepay_total,
|
|
|
"customer_balance" => $order->customer->balance,
|
|
|
"to_refund_total" => $to_refund_total,
|
|
|
"refund_payment" => $recharge_for_online_refund ? $recharge_for_online_refund->payment : "cash",
|
|
|
"refund_recharge_id" => $recharge_for_online_refund ? $recharge_for_online_refund->id : null,
|
|
|
"refund_recharge_transaction_id" => $recharge_for_online_refund ? $recharge_for_online_refund->payment_serial : null
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
//3、账务平衡可结单
|
|
|
DB::beginTransaction();
|
|
|
try {
|
|
|
foreach ($unpaid_order_items as $order_item) {
|
|
|
//更新子订单支付状态
|
|
|
$order_item->update(["paid_at" => date("Y-m-d H:i:s")]);
|
|
|
|
|
|
//更新客户余额(暂不保存,最后统一保存)
|
|
|
$order->customer->balance = $order->customer->balance - $order_item->total;
|
|
|
|
|
|
//创建收款记录
|
|
|
(new Balance())->create([
|
|
|
"customer_id" => $order->customer->id,
|
|
|
"order_id" => $order->id,
|
|
|
"belongs_type" => get_class($order_item),
|
|
|
"belongs_id" => $order_item->id,
|
|
|
"money" => -$order_item->total,
|
|
|
"balance" => $order->customer->balance
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
for ($i = 0; $i < $to_generate_days; $i++) {
|
|
|
if ($i > 0) {
|
|
|
$service_date = Carbon::parse($to_generate_start_date)->addDays($i)->toDateString();
|
|
|
} else {
|
|
|
$service_date = $to_generate_start_date;
|
|
|
}
|
|
|
$order_item = (new OrderItems())->createItem($order->id, $service_date);
|
|
|
//更新子订单支付状态
|
|
|
$order_item->update(["paid_at" => date("Y-m-d H:i:s")]);
|
|
|
|
|
|
//更新客户余额(暂不保存,最后统一保存)
|
|
|
$order->customer->balance = $order->customer->balance - $order_item->total;
|
|
|
|
|
|
//创建收款记录
|
|
|
(new Balance())->create([
|
|
|
"customer_id" => $order->customer->id,
|
|
|
"order_id" => $order->id,
|
|
|
"belongs_type" => get_class($order_item),
|
|
|
"belongs_id" => $order_item->id,
|
|
|
"money" => -$order_item->total,
|
|
|
"balance" => $order->customer->balance
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
$order->customer->save();
|
|
|
$order->update([
|
|
|
"status" => Orders::STATUS_FINISHED,
|
|
|
"to_date" => $request->to_date
|
|
|
]);
|
|
|
|
|
|
DB::commit();
|
|
|
return response()->json([
|
|
|
"checkout_order_id" => $order->id
|
|
|
]);
|
|
|
} catch (\Exception $exception) {
|
|
|
DB::rollBack();
|
|
|
return response()->json([
|
|
|
"errorcode" => $exception->getCode(),
|
|
|
"errormsg" => $exception->getMessage()
|
|
|
]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\POST(
|
|
|
* path="/manager/scan-pay/{order_id}",
|
|
|
* tags={"管理端订单处理"},
|
|
|
* summary="V2-扫用户支付码收款",
|
|
|
* description="扫用户支付码收款",
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Parameter(name="order_id", in="path", @OA\Schema(type="integer"), required=true, description="订单id"),
|
|
|
* @OA\Parameter(name="money", in="query", @OA\Schema(type="number"), required=true, description="支付金额"),
|
|
|
* @OA\Parameter(name="auth_code", in="query", @OA\Schema(type="string"), required=true, description="扫码后获取的支付码"),
|
|
|
* @OA\Parameter(name="type", in="query", @OA\Schema(type="string"), required=true, description="支付方式:weixin,alipay"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="扫用户支付码收款"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
public function scanPay($order_id)
|
|
|
{
|
|
|
if (request()->money <= 0) {
|
|
|
return response()->json([
|
|
|
"errorcode" => 60003,
|
|
|
"errormsg" => "付款金额不正确"
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
$order = (new Orders())->with("wechatpayAccount")->find($order_id);
|
|
|
$recharge = (new Recharge())->create([
|
|
|
"customer_id" => $order->customer->id,
|
|
|
"money" => request()->money,
|
|
|
"order_id" => $order->id,
|
|
|
"payment" => request()->type,
|
|
|
"manager_id" => $this->manager->id
|
|
|
]);
|
|
|
$recharge = $recharge->getSerial();
|
|
|
|
|
|
switch (request()->type) {
|
|
|
case "weixin":
|
|
|
$res = (new WxMicroPay($order->project_id))->pay($recharge);
|
|
|
$recharge->update([
|
|
|
"merchant_id" => $order->wechatpayAccount->mchid
|
|
|
]);
|
|
|
|
|
|
if ($res === true) {
|
|
|
return response()->json(true);
|
|
|
} else {
|
|
|
return response()->json([
|
|
|
"errorcode" => 60003,
|
|
|
"errormsg" => $res->getMessage()
|
|
|
]);
|
|
|
}
|
|
|
break;
|
|
|
case "alipay":
|
|
|
$res = (new AlipayF2F())->pay($recharge);
|
|
|
$recharge->update([
|
|
|
"merchant_id" => env("ALI_APP_ID")
|
|
|
]);
|
|
|
if ($res["status"]) {
|
|
|
return response()->json(true);
|
|
|
} else {
|
|
|
return response()->json([
|
|
|
"errorcode" => $res["code"],
|
|
|
"errormsg" => $res["msg"]
|
|
|
]);
|
|
|
}
|
|
|
break;
|
|
|
default:
|
|
|
return response()->json([
|
|
|
"errorcode" => 60003,
|
|
|
"errormsg" => "不正确的支付方式"
|
|
|
]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\POST(
|
|
|
* path="/manager/assign-order/{id}",
|
|
|
* tags={"管理端订单处理"},
|
|
|
* summary="V2-派单",
|
|
|
* description="派单",
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Parameter(name="id", in="path", @OA\Schema(type="integer"), required=true, description="订单id"),
|
|
|
* @OA\Parameter(name="paramedic_id", in="query", @OA\Schema(type="integer"), required=true, description="护工id"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="订单派单",
|
|
|
* content={
|
|
|
* @OA\MediaType(
|
|
|
* mediaType="application/json",
|
|
|
* @OA\Schema(
|
|
|
* @OA\Property(
|
|
|
* property="errorcode",
|
|
|
* type="integer",
|
|
|
* description="错误码;仅在发生错误时发送"
|
|
|
* ),
|
|
|
* @OA\Property(
|
|
|
* property="errormsg",
|
|
|
* type="string",
|
|
|
* description="返回消息;有errorcode时为错误内容,无errorcode时为提示内容"
|
|
|
* ),
|
|
|
* @OA\Property(
|
|
|
* property="order.*",
|
|
|
* type="string",
|
|
|
* description="订单实体"
|
|
|
* ),
|
|
|
* @OA\Property(
|
|
|
* property="affected_orders",
|
|
|
* type="array",
|
|
|
* @OA\Items(),
|
|
|
* description="特别说明:影响到的订单,如果无此字段或数组为空表示未发生订单影响。影响到的订单实体数组,实体中的change字段(many_to_one或one_to_many)表示影响的方向"
|
|
|
* )
|
|
|
* )
|
|
|
* )
|
|
|
* }
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
|
|
|
public function assignOrder($id)
|
|
|
{
|
|
|
$order = (new Orders())->find($id);
|
|
|
if (!in_array($order->status, [Orders::STATUS_UNCONFIRMED, Orders::STATUS_UNASSIGNED])) {
|
|
|
return response()->json([
|
|
|
"errorcode" => 50001,
|
|
|
"errormsg" => "订单状态不适配"
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
DB::beginTransaction();
|
|
|
try {
|
|
|
$order->update([
|
|
|
"paramedic_id" => request()->paramedic_id,
|
|
|
"status" => Orders::STATUS_ONGOING
|
|
|
]);
|
|
|
event(new OrderAssigned($order));
|
|
|
DB::commit();
|
|
|
return response()->json($order);
|
|
|
} catch (\Exception $exception) {
|
|
|
DB::rollBack();
|
|
|
return response()->json([
|
|
|
"errorcode" => $exception->getCode(),
|
|
|
"errormsg" => $exception->getMessage()
|
|
|
]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\POST(
|
|
|
* path="/manager/cancel-order/{id}",
|
|
|
* tags={"管理端订单处理"},
|
|
|
* summary="V2-取消订单",
|
|
|
* description="取消订单",
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Parameter(name="id", in="path", @OA\Schema(type="integer"), required=true, description="订单id"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="取消订单"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
|
|
|
public function cancelOrder($id)
|
|
|
{
|
|
|
$order = (new Orders())->with("orderItems")->find($id);
|
|
|
if (!in_array($order->status, [Orders::STATUS_UNCONFIRMED, Orders::STATUS_UNASSIGNED])) {
|
|
|
return response()->json([
|
|
|
"errorcode" => 50001,
|
|
|
"errormsg" => "订单状态不适配"
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
DB::beginTransaction();
|
|
|
try {
|
|
|
// 1. 获取订单的微信支付记录
|
|
|
$recharges = (new Recharge())
|
|
|
->where("order_id", $order->id)
|
|
|
->whereNotNull("paid_at")
|
|
|
->doesntHave("refunds")
|
|
|
->where("payment", "weixin")
|
|
|
->get();
|
|
|
|
|
|
// 2. 计算支付总额
|
|
|
$totalPaid = (float)$recharges->sum('money');
|
|
|
|
|
|
// 3. 获取用户当前余额
|
|
|
$customer = $order->customer;
|
|
|
$currentBalance = (float)$customer->balance;
|
|
|
|
|
|
// 4. 如果支付总额等于用户余额,进行退款处理
|
|
|
if ($totalPaid > 0 && float_equals($totalPaid, $currentBalance)) {
|
|
|
foreach ($recharges as $recharge) {
|
|
|
// 更新用户余额
|
|
|
$currentBalance -= $recharge->money;
|
|
|
$customer->balance = $currentBalance;
|
|
|
$customer->save();
|
|
|
// 生成退款记录与财务记录
|
|
|
$refund = Refund::create([
|
|
|
"customer_id" => $order->customer->id,
|
|
|
"money" => $recharge->money,
|
|
|
"order_id" => $order->id,
|
|
|
"payment" => $recharge->payment,
|
|
|
"recharge_id" => $recharge->id,
|
|
|
"merchant_id" => $recharge->merchant_id,
|
|
|
"remark" => "取消订单,自动退款"
|
|
|
]);
|
|
|
$refund->getSerial();
|
|
|
|
|
|
$balance = Balance::create([
|
|
|
"customer_id" => $customer->id,
|
|
|
"order_id" => $order->id,
|
|
|
"belongs_type" => get_class($refund),
|
|
|
"belongs_id" => $refund->id,
|
|
|
"money" => -$refund->money,
|
|
|
"balance" => $currentBalance
|
|
|
]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 5. 删除订单及子订单
|
|
|
foreach ($order->orderItems as $orderItem) {
|
|
|
$orderItem->delete();
|
|
|
}
|
|
|
$order->delete();
|
|
|
|
|
|
DB::commit();
|
|
|
return response()->json($order);
|
|
|
} catch (\Exception $exception) {
|
|
|
DB::rollBack();
|
|
|
return response()->json([
|
|
|
"errorcode" => $exception->getCode(),
|
|
|
"errormsg" => $exception->getMessage()
|
|
|
]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\POST(
|
|
|
* path="/manager/get-balance/{customer_id}",
|
|
|
* tags={"管理端订单处理"},
|
|
|
* summary="获取用户余额",
|
|
|
* description="获取用户余额",
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Parameter(name="customer_id", in="path", @OA\Schema(type="integer"), required=true, description="用户id"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="获取用户余额"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
public function getBalance($customer_id)
|
|
|
{
|
|
|
$customer = (new Customer())->find($customer_id);
|
|
|
if (!$customer) {
|
|
|
return response()->json([
|
|
|
"errorcode" => 70001,
|
|
|
"errormsg" => "没找到用户信息"
|
|
|
]);
|
|
|
}
|
|
|
return response()->json([
|
|
|
"balance" => $customer->balance
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\POST(
|
|
|
* path="/manager/recharge-for-order/{id}",
|
|
|
* tags={"管理端订单处理"},
|
|
|
* summary="V2-现金或pos刷卡充值",
|
|
|
* description="现金或pos刷卡充值",
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Parameter(name="id", in="path", @OA\Schema(type="integer"), required=true, description="订单id"),
|
|
|
* @OA\Parameter(name="payment", in="query", @OA\Schema(type="string"), required=true, description="枚举:pos=>pos机刷卡支付, cash=>现金支付"),
|
|
|
* @OA\Parameter(name="money", in="query", @OA\Schema(type="number"), required=true, description="金额,非负数"),
|
|
|
* @OA\Parameter(name="remark", in="query", @OA\Schema(type="string"), required=false, description="备注信息:现金支付时可以忽略;刷卡支付时,填入回单号或卡号以便财务对账"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="现金或pos刷卡充值"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
|
|
|
public function rechargeForOrder($id)
|
|
|
{
|
|
|
$order = (new Orders())->find($id);
|
|
|
if ($order->status != Orders::STATUS_ONGOING) {
|
|
|
return response()->json([
|
|
|
"errorcode" => 30000,
|
|
|
"errormsg" => "订单状态不匹配"
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
DB::beginTransaction();
|
|
|
try {
|
|
|
//创建充值记录
|
|
|
$recharge = [
|
|
|
"customer_id" => $order->customer->id,
|
|
|
"money" => request()->money,
|
|
|
"order_id" => $order->id,
|
|
|
"payment" => request()->payment,
|
|
|
"manager_id" => $this->manager->id,
|
|
|
"paid_at" => date("Y-m-d H:i:s")
|
|
|
];
|
|
|
switch (request()->payment) {
|
|
|
case "pos":
|
|
|
case "cash":
|
|
|
$recharge["remark"] = request()->remark;
|
|
|
break;
|
|
|
default:
|
|
|
return response()->json([
|
|
|
"errorcode" => "0",
|
|
|
"errormsg" => "不正确的支付方式"
|
|
|
]);
|
|
|
}
|
|
|
$recharge = (new Recharge())->create($recharge);
|
|
|
$recharge = $recharge->getSerial();
|
|
|
|
|
|
//更新用户余额,创建流水记录
|
|
|
$customer_balance = $recharge->customer->balance + $recharge->money;
|
|
|
$recharge->customer->update([
|
|
|
"balance" => $customer_balance
|
|
|
]);
|
|
|
$balance = (new Balance())->create([
|
|
|
"customer_id" => $recharge->customer->id,
|
|
|
"order_id" => $recharge->order_id,
|
|
|
"belongs_type" => get_class($recharge),
|
|
|
"belongs_id" => $recharge->id,
|
|
|
"money" => $recharge->money,
|
|
|
"balance" => $customer_balance
|
|
|
]);
|
|
|
DB::commit();
|
|
|
return response()->json([
|
|
|
"recharge" => $recharge,
|
|
|
"balance" => $balance
|
|
|
]);
|
|
|
} catch (\Exception $exception) {
|
|
|
DB::rollBack();
|
|
|
return response()->json([
|
|
|
"errorcode" => $exception->getCode(),
|
|
|
"errormsg" => $exception->getMessage()
|
|
|
]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\POST(
|
|
|
* path="/manager/refund-for-order/{id}",
|
|
|
* tags={"管理端订单处理"},
|
|
|
* summary="V2-退款",
|
|
|
* description="退款",
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Parameter(name="id", in="path", @OA\Schema(type="integer"), required=true, description="订单id"),
|
|
|
* @OA\Parameter(name="money", in="query", @OA\Schema(type="number"), required=true, description="金额,非负数"),
|
|
|
* @OA\Parameter(name="payment", in="query", @OA\Schema(type="string"), required=true, description="退款方式:枚举cash,weixin,alipay。注意可用的退款方式从支付明细或结单时的交互反馈得出,随意提交金额可能会造成问题"),
|
|
|
* @OA\Parameter(name="recharge_id", in="query", @OA\Schema(type="integer"), required=false, description="相关在线支付的id,用于原路返回。退款方式为weixin或alipay时,必须给出"),
|
|
|
* @OA\Parameter(name="remark", in="query", @OA\Schema(type="string"), required=false, description="备注信息"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="退款"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
public function refundForOrder($id)
|
|
|
{
|
|
|
DB::beginTransaction();
|
|
|
try {
|
|
|
$order = (new Orders())->find($id);
|
|
|
//创建退款记录
|
|
|
$refund = [
|
|
|
"customer_id" => $order->customer->id,
|
|
|
"manager_id" => $this->manager->id,
|
|
|
"money" => request()->money,
|
|
|
"order_id" => $order->id,
|
|
|
"remark" => request()->remark
|
|
|
];
|
|
|
|
|
|
switch (request()->payment) {
|
|
|
case "cash":
|
|
|
case "pos":
|
|
|
$refund["payment"] = request()->payment;
|
|
|
$refund["paid_at"] = date("Y-m-d H:i:s");
|
|
|
break;
|
|
|
case "weixin":
|
|
|
$recharge = Recharge::find(request()->recharge_id);
|
|
|
$refund["payment"] = $recharge->payment;
|
|
|
$refund["recharge_id"] = request()->recharge_id;
|
|
|
$refund["merchant_id"] = $recharge->merchant_id;
|
|
|
break;
|
|
|
case "alipay":
|
|
|
$recharge = Recharge::find(request()->recharge_id);
|
|
|
if (!$recharge->merchant_id) {
|
|
|
return response()->json([
|
|
|
"errorcode" => "0",
|
|
|
"errormsg" => "本单支付宝退款暂不支持"
|
|
|
]);
|
|
|
}
|
|
|
$refund["payment"] = $recharge->payment;
|
|
|
$refund["recharge_id"] = request()->recharge_id;
|
|
|
$refund["merchant_id"] = $recharge->merchant_id;
|
|
|
break;
|
|
|
default:
|
|
|
return response()->json([
|
|
|
"errorcode" => "0",
|
|
|
"errormsg" => "不正确的退款方式"
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
$refund = (new Refund())->create($refund);
|
|
|
$refund = $refund->getSerial();
|
|
|
|
|
|
//更新用户余额,创建流水记录
|
|
|
$customer_balance = $refund->customer->balance - $refund->money;
|
|
|
if ($customer_balance < 0) {
|
|
|
return response()->json([
|
|
|
"errorcode" => "0",
|
|
|
"errormsg" => "客户余额为负异常,存在重复退款操作。"
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
$refund->customer->update([
|
|
|
"balance" => $customer_balance
|
|
|
]);
|
|
|
$balance = (new Balance())->create([
|
|
|
"customer_id" => $refund->customer->id,
|
|
|
"order_id" => $refund->order_id,
|
|
|
"belongs_type" => get_class($refund),
|
|
|
"belongs_id" => $refund->id,
|
|
|
"money" => -$refund->money,
|
|
|
"balance" => $customer_balance
|
|
|
]);
|
|
|
DB::commit();
|
|
|
return response()->json([
|
|
|
"refund" => $refund,
|
|
|
"balance" => $balance
|
|
|
]);
|
|
|
} catch (\Exception $exception) {
|
|
|
DB::rollBack();
|
|
|
return response()->json([
|
|
|
"errorcode" => $exception->getCode(),
|
|
|
"errormsg" => $exception->getMessage()
|
|
|
]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\Get(
|
|
|
* path="/manager/get-project-paramedic-levels/{project_id}",
|
|
|
* tags={"管理端订单处理"},
|
|
|
* summary="V2-获取医院护工等级",
|
|
|
* description="获取医院护工等级",
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Parameter(name="project_id", in="query", @OA\Schema(type="string"), required=true, description="医院ID"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="获取医院护工等级"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
public function getProjectParamedicLevels($project_id)
|
|
|
{
|
|
|
$paramedic_levels = ParamedicLevel::where("project_id", $project_id)->orderBy("myindex")->get();
|
|
|
return response()->json($paramedic_levels->toArray());
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\Post(
|
|
|
* path="/manager/change-order-status/{id}",
|
|
|
* tags={"管理端订单处理"},
|
|
|
* summary="V2-更新订单状态,20230618更新:鉴定是否权限是否开启",
|
|
|
* description="更新订单状态",
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Parameter(name="from_status", in="query", @OA\Schema(type="integer"), required=true, description="原状态"),
|
|
|
* @OA\Parameter(name="to_status", in="query", @OA\Schema(type="integer"), required=true, description="更新状态"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="更新订单状态"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
|
|
|
public function changeOrderStatus($id)
|
|
|
{
|
|
|
try {
|
|
|
$manager = $this->guard()->user();
|
|
|
if (!$manager->order_status_ability) {
|
|
|
return response()->json([
|
|
|
"errorcode" => "4003",
|
|
|
"errormsg" => "权限不足"
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
$order = (new Orders())->find($id);
|
|
|
if (request()->to_status == Orders::STATUS_ONGOING) {
|
|
|
$other_ongoing_order = Orders::where("status", Orders::STATUS_ONGOING)->where("customer_id", $order->customer_id)->count();
|
|
|
if ($other_ongoing_order) {
|
|
|
return response()->json([
|
|
|
"errorcode" => "2222",
|
|
|
"errormsg" => "客户名下有其他进行中的该订单"
|
|
|
]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
$res = (new ChangeOrderStatus())->__invoke($order);
|
|
|
DB::commit();
|
|
|
return response()->json($order->toArray());
|
|
|
} catch (\Exception $exception) {
|
|
|
DB::rollBack();
|
|
|
return response()->json([
|
|
|
"errorcode" => $exception->getCode(),
|
|
|
"errormsg" => $exception->getMessage()
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\Post(
|
|
|
* path="/manager/create-order-agreements",
|
|
|
* tags={"管理端订单处理"},
|
|
|
* summary="创建协议",
|
|
|
* description="创建协议",
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Parameter(name="order_id", in="query", @OA\Schema(type="integer"), required=true, description="订单id"),
|
|
|
* @OA\Parameter(name="paramedic_id", in="query", @OA\Schema(type="integer"), required=true, description="护工id"),
|
|
|
* @OA\Parameter(name="paramedic_id", in="query", @OA\Schema(type="integer"), required=true, description="护工id"),
|
|
|
* @OA\Parameter(name="paramedic_sign_id", in="query", @OA\Schema(type="integer"), required=true, description="护工签名图片id"),
|
|
|
* @OA\Parameter(name="customer_id", in="query", @OA\Schema(type="integer"), required=true, description="客户id"),
|
|
|
* @OA\Parameter(name="customer_sign_id", in="query", @OA\Schema(type="integer"), required=true, description="客户签名图片id"),
|
|
|
* @OA\Parameter(name="company_sign_id", in="query", @OA\Schema(type="integer"), required=true, description="公司签名图片id"),
|
|
|
* @OA\Parameter(name="file_id", in="query", @OA\Schema(type="integer"), required=true, description="协议文件id"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="更新订单状态"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
public function createOrderAgreements()
|
|
|
{
|
|
|
$all = \request()->all();
|
|
|
$orderAgreement = orderAgreement::create($all);
|
|
|
return response()->json($orderAgreement->toArray());
|
|
|
}
|
|
|
|
|
|
}
|