|
|
@@ -0,0 +1,171 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace App\Services;
|
|
|
+
|
|
|
+use App\LaborCompany;
|
|
|
+use App\LaborCompanyDispatch;
|
|
|
+use App\Traits\ServiceAppAop;
|
|
|
+use App\LaborApply;
|
|
|
+use App\Warehouse;
|
|
|
+use Illuminate\Database\Eloquent\Builder;
|
|
|
+use Illuminate\Database\Eloquent\Collection;
|
|
|
+use Illuminate\Support\Facades\Cache;
|
|
|
+use Illuminate\Support\Facades\DB;
|
|
|
+
|
|
|
+class LaborApplyService
|
|
|
+{
|
|
|
+ //超时时间 默认为19:00
|
|
|
+ const TIME_OUT_HOUR = 19;
|
|
|
+ const LABOR_APPLY_STATUS = 'LABOR_APPLY_STATUS';
|
|
|
+ const LABOR_APPLY_STATUS_TTL = 60 * 30;
|
|
|
+ use ServiceAppAop;
|
|
|
+
|
|
|
+ protected $modelClass = LaborApply::class;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取预约开放状态
|
|
|
+ *
|
|
|
+ * @return int 1 开放 2 禁止 3 临时开放
|
|
|
+ */
|
|
|
+ public function getCanCreateStatus(): int
|
|
|
+ {
|
|
|
+ $can_create_status = (now()->lte(now()->startOfDay()->addHours(self::TIME_OUT_HOUR))) ? LaborApply::CAN_CREATE_STATUS_OPEN : LaborApply::CAN_CREATE_STATUS_FORBID;
|
|
|
+ if (Cache::has(self::LABOR_APPLY_STATUS)) {
|
|
|
+ $can_create_status = Cache::get(self::LABOR_APPLY_STATUS);
|
|
|
+ }
|
|
|
+ return $can_create_status;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设置预约开放状态 1 开放 2 禁止 3 临时开放
|
|
|
+ * @param int $status
|
|
|
+ */
|
|
|
+ public function setCanCreateStatus(int $status)
|
|
|
+ {
|
|
|
+ Cache::put(self::LABOR_APPLY_STATUS, $status, self::LABOR_APPLY_STATUS_TTL);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生产劳务派遣报表
|
|
|
+ *
|
|
|
+ * 查询全部仓库
|
|
|
+ * 遍历仓库
|
|
|
+ * 按照仓库,查询当日的的申请,将申请的男女工分别加和
|
|
|
+ * 按照仓库查询对应的劳务所 按照优先级排序
|
|
|
+ * 将男女工之和依次分配到 劳务所
|
|
|
+ * 如果分配完成后 发现还有剩下的 则将状态设置为2
|
|
|
+ */
|
|
|
+ public function allocationLaborToLaborCompany(): array
|
|
|
+ {
|
|
|
+
|
|
|
+ //当前时间小于 1.00 禁止生成数据
|
|
|
+ if (now()->lte(now()->startOfDay()->addHours(1))) return ['success' => false, 'error_message' => '当前时间禁止生成临时工派遣数据'];
|
|
|
+ //派遣日期 为报表生成日期的后一天
|
|
|
+ $dispatch_date = now()->addDay()->startOfDay()->toDateTimeString();
|
|
|
+
|
|
|
+ //接口幂等性,删除旧的数据
|
|
|
+ LaborCompanyDispatch::query()->where('dispatch_date', $dispatch_date)->delete();
|
|
|
+
|
|
|
+ //查询全部仓库
|
|
|
+ $warehouses = Warehouse::all();
|
|
|
+ //按照仓库,
|
|
|
+ foreach ($warehouses as $warehouse) {
|
|
|
+ //查询当日的的申请,将申请的男女工分别加和
|
|
|
+ $apply_man_nums = DB::table('labor_applies')
|
|
|
+ ->selectRaw("sum(man_num) as man_num ,sum(woman_num) as woman_num")
|
|
|
+ ->whereBetween('created_at', [now()->startOfDay(), now()->endOfDay()])
|
|
|
+ ->where('warehouse_id', $warehouse->id)
|
|
|
+ ->groupBy('warehouse_id')
|
|
|
+ ->first();
|
|
|
+ if (empty($apply_man_nums)) continue;
|
|
|
+ //按照仓库查询对应的劳务所 按照优先级排序 单号正序 双号逆序
|
|
|
+ $companies = $this->getCompaniesOrderByDay($warehouse);
|
|
|
+ //需要的男工人数
|
|
|
+ $man_num = $apply_man_nums->man_num;
|
|
|
+ //需要的女工人数
|
|
|
+ $woman_num = $apply_man_nums->woman_num;
|
|
|
+ //插入的分配数据
|
|
|
+ $laborCompanyDispatchInsertArray = $this->buildLaborCompanyDispatchInsertArray($companies, $man_num, $woman_num, $dispatch_date);
|
|
|
+ //插入分配数据
|
|
|
+ LaborCompanyDispatch::query()->insert($laborCompanyDispatchInsertArray);
|
|
|
+
|
|
|
+ LaborApply::query()
|
|
|
+ ->whereBetween('created_at', [now()->startOfDay(), now()->endOfDay()])
|
|
|
+ ->where('warehouse_id', $warehouse->id)
|
|
|
+ ->update([
|
|
|
+ 'status' => 2,//指派成功
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+ return ['success' => true, 'message' => '生成临时工派遣数据成功'];
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设置为状态为溢出
|
|
|
+ * @param array $laborCompanyAppliesTarget
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ private function setExceedMaxLaborNumStatusExceedMaxLaborNum(array $laborCompanyAppliesTarget): array
|
|
|
+ {
|
|
|
+ return array_map(function (&$item) {
|
|
|
+ $item['exceed_max_labor_num_status'] = LaborCompanyDispatch::EXCEED_MAX_LABOR_NUM;
|
|
|
+ return $item;
|
|
|
+ }, $laborCompanyAppliesTarget);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构建插入的分配数据
|
|
|
+ * @param $companies
|
|
|
+ * @param $man_num
|
|
|
+ * @param $woman_num
|
|
|
+ * @param string $dispatch_date
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ private function buildLaborCompanyDispatchInsertArray($companies, $man_num, $woman_num, string $dispatch_date): array
|
|
|
+ {
|
|
|
+ $laborCompanyDispatchInsertArray = [];
|
|
|
+ //遍历劳务公司
|
|
|
+ foreach ($companies as $company) {
|
|
|
+ if ($man_num > 0 || $woman_num > 0) {
|
|
|
+ //分配给指定劳务的男工人数
|
|
|
+ $dispatch_man_num = $man_num > $company->man_num ? $company->man_num : $man_num;
|
|
|
+ //分配给指定劳务的女工人数
|
|
|
+ $dispatch_woman_num = $woman_num > $company->woman_num ? $company->woman_num : $woman_num;
|
|
|
+ //待分配的男工
|
|
|
+ $man_num -= $dispatch_man_num;
|
|
|
+ //待分配的女工
|
|
|
+ $woman_num -= $dispatch_woman_num;
|
|
|
+ $laborCompanyDispatchInsertArray[] = [
|
|
|
+ 'labor_company_id' => $company->id,
|
|
|
+ 'man_num' => $dispatch_man_num,
|
|
|
+ 'woman_num' => $dispatch_woman_num,
|
|
|
+ 'dispatch_date' => $dispatch_date,
|
|
|
+ 'exceed_max_labor_num_status' => LaborCompanyDispatch::NOT_EXCEED_MAX_LABOR_NUM,//没有超限额
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ //全部劳务公司分配完后 还有剩余的男工/女工
|
|
|
+ if ($man_num > 0 || $woman_num > 0) {
|
|
|
+ //设置状态为超额
|
|
|
+ $laborCompanyDispatchInsertArray = $this->setExceedMaxLaborNumStatusExceedMaxLaborNum($laborCompanyDispatchInsertArray);
|
|
|
+ }
|
|
|
+ return $laborCompanyDispatchInsertArray;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 按照仓库查询对应的劳务所 按照优先级排序 单号正序 双号逆序
|
|
|
+ * @param $warehouse
|
|
|
+ * @return Builder[]|Collection
|
|
|
+ */
|
|
|
+ private function getCompaniesOrderByDay($warehouse)
|
|
|
+ {
|
|
|
+ $builder = LaborCompany::query()
|
|
|
+ ->where('warehouse_id', $warehouse->id);
|
|
|
+ if (now()->day % 2 === 0) {
|
|
|
+ $builder->orderBy('priority');
|
|
|
+ } else {
|
|
|
+ $builder->orderBy('priority', 'desc');
|
|
|
+ }
|
|
|
+ return $builder->get();
|
|
|
+ }
|
|
|
+}
|