117 lines
3.9 KiB
PHP
117 lines
3.9 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Recon;
|
|
|
|
use App\Exceptions\RepositoryException;
|
|
use App\Models\BillModel;
|
|
use App\Services\BillDetailService;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Modules\AnnoRoute\Attribute\GetRoute;
|
|
use Modules\AnnoRoute\Attribute\PutRoute;
|
|
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
|
use Modules\Common\Http\Controllers\BaseController;
|
|
|
|
/**
|
|
* 门店账单管理(采购单完成后按门店生成,后台查看 + 线下收款登记)
|
|
*/
|
|
#[RequestAttribute('/recon/bill', 'recon.bill')]
|
|
class BillController extends BaseController
|
|
{
|
|
protected array $searchField = [
|
|
'store_id' => '=',
|
|
'status' => '=',
|
|
'bill_no' => 'like',
|
|
'bill_date' => 'betweenDate',
|
|
];
|
|
|
|
/** 账单列表 */
|
|
#[GetRoute(authorize: 'query')]
|
|
public function query(Request $request): JsonResponse
|
|
{
|
|
$params = $request->all();
|
|
$pageSize = $params['pageSize'] ?? 10;
|
|
$query = BillModel::query()->with([
|
|
'store:id,name',
|
|
'purchase:id,purchase_no,purchase_date',
|
|
'operator:id,nickname',
|
|
])->withCount('orders');
|
|
|
|
// 按采购单号搜索
|
|
$purchaseNo = trim((string) ($params['purchase_no'] ?? ''));
|
|
if ($purchaseNo !== '') {
|
|
$keyword = '%' . str_replace('%', '\%', $purchaseNo) . '%';
|
|
$query->whereHas('purchase', static function ($purchaseQuery) use ($keyword) {
|
|
$purchaseQuery->where('purchase_no', 'like', $keyword);
|
|
});
|
|
}
|
|
|
|
$data = $this->buildSearch($params, $query)
|
|
->orderBy('bill_date', 'desc')
|
|
->orderBy('id', 'desc')
|
|
->paginate($pageSize)
|
|
->toArray();
|
|
|
|
return $this->success($data);
|
|
}
|
|
|
|
/**
|
|
* 账单详情:账单信息 + 合并后的商品明细(按商品聚合)+ 关联订单
|
|
*/
|
|
#[GetRoute(route: '/{id}', authorize: 'query', where: ['id' => '[0-9]+'])]
|
|
public function detail(int $id): JsonResponse
|
|
{
|
|
$bill = BillModel::with([
|
|
'store:id,name,address,contact,phone',
|
|
'purchase:id,purchase_no,purchase_date,status',
|
|
'operator:id,nickname',
|
|
'paidOperator:id,nickname',
|
|
])->find($id);
|
|
if (empty($bill)) {
|
|
throw new RepositoryException('账单不存在');
|
|
}
|
|
|
|
$orders = $bill->orders()
|
|
->orderBy('id')
|
|
->get(['id', 'order_no', 'order_date', 'total_quantity', 'total_weight', 'total_amount', 'status'])
|
|
->toArray();
|
|
|
|
return $this->success([
|
|
'bill' => $bill->toArray(),
|
|
'items' => app(BillDetailService::class)->mergedItems($bill),
|
|
'orders' => $orders,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 确认收款:线下收款后手动登记付款信息,支付状态置为已支付
|
|
*/
|
|
#[PutRoute(route: '/{id}/pay', authorize: 'pay', where: ['id' => '[0-9]+'])]
|
|
public function pay(int $id, Request $request): JsonResponse
|
|
{
|
|
$data = $request->validate([
|
|
'paid_at' => 'sometimes|date_format:Y-m-d H:i:s',
|
|
'pay_remark' => 'nullable|string|max:255',
|
|
], [
|
|
'paid_at.date_format' => '付款时间格式为 Y-m-d H:i:s',
|
|
'pay_remark.max' => '付款备注超过最大长度',
|
|
]);
|
|
|
|
$bill = BillModel::find($id);
|
|
if (empty($bill)) {
|
|
throw new RepositoryException('账单不存在');
|
|
}
|
|
if ($bill->status === BillModel::STATUS_PAID) {
|
|
throw new RepositoryException('账单已支付,请勿重复收款');
|
|
}
|
|
|
|
$bill->status = BillModel::STATUS_PAID;
|
|
$bill->paid_at = $data['paid_at'] ?? now();
|
|
$bill->pay_remark = (string) ($data['pay_remark'] ?? '');
|
|
$bill->paid_operator_id = (int) $request->user()->id;
|
|
$bill->save();
|
|
|
|
return $this->success([], '收款已登记');
|
|
}
|
|
}
|