|
|
@@ -2,13 +2,17 @@
|
|
|
|
|
|
namespace App\Service;
|
|
|
|
|
|
+use App\Model\DailyPwOrder;
|
|
|
+use App\Model\DailyPwOrderDetails;
|
|
|
use App\Model\Employee;
|
|
|
+use App\Model\Item;
|
|
|
use App\Model\MonthlyPwOrder;
|
|
|
use App\Model\MonthlyPwOrderDetails;
|
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
|
|
class PersonWorkService extends Service
|
|
|
{
|
|
|
+ // 人员月工时单-------------------------------------------
|
|
|
public function monthlyPwOrderEdit($data,$user){
|
|
|
list($status,$msg) = $this->monthlyPwOrderRule($data, $user, false);
|
|
|
if(!$status) return [$status,$msg];
|
|
|
@@ -307,4 +311,343 @@ class PersonWorkService extends Service
|
|
|
}
|
|
|
return $res; // 返回 [main_id => [detail_row, detail_row]]
|
|
|
}
|
|
|
+
|
|
|
+ // 人员日工时单 ------------------------------------------------
|
|
|
+
|
|
|
+ public function dailyPwOrderEdit($data,$user){
|
|
|
+ list($status,$msg) = $this->dailyPwOrderRule($data, $user, false);
|
|
|
+ if(!$status) return [$status,$msg];
|
|
|
+
|
|
|
+ try {
|
|
|
+ DB::beginTransaction();
|
|
|
+
|
|
|
+ $model = DailyPwOrder::where('id',$data['id'])->first();
|
|
|
+ $model->item_id = $data['item_id'] ?? 0;
|
|
|
+ $model->save();
|
|
|
+
|
|
|
+ $time = time();
|
|
|
+ DailyPwOrderDetails::where('del_time',0)
|
|
|
+ ->where('main_id', $model->id)
|
|
|
+ ->update(['del_time' => $time]);
|
|
|
+ $this->saveDetailDaily($model->id, $time, $data);
|
|
|
+
|
|
|
+ DB::commit();
|
|
|
+ }catch (\Exception $exception){
|
|
|
+ DB::rollBack();
|
|
|
+ return [false,$exception->getMessage()];
|
|
|
+ }
|
|
|
+
|
|
|
+ return [true, ''];
|
|
|
+ }
|
|
|
+
|
|
|
+ public function dailyPwOrderAdd($data,$user){
|
|
|
+ list($status,$msg) = $this->dailyPwOrderRule($data, $user);
|
|
|
+ if(!$status) return [$status,$msg];
|
|
|
+
|
|
|
+ try {
|
|
|
+ DB::beginTransaction();
|
|
|
+
|
|
|
+ $model = new DailyPwOrder();
|
|
|
+ $model->code = $this->generateBillNo([
|
|
|
+ 'top_depart_id' => $user['top_depart_id'],
|
|
|
+ 'type' => DailyPwOrder::Order_type,
|
|
|
+ 'period' => date("Ym", $data['order_time'])
|
|
|
+ ]);
|
|
|
+ $model->order_time = $data['order_time'] ?? 0;
|
|
|
+ $model->item_id = $data['item_id'] ?? 0;
|
|
|
+ $model->crt_id = $user['id'];
|
|
|
+ $model->top_depart_id = $data['top_depart_id'];
|
|
|
+ $model->save();
|
|
|
+
|
|
|
+ $this->saveDetailDaily($model->id, time(), $data);
|
|
|
+
|
|
|
+ DB::commit();
|
|
|
+ }catch (\Exception $exception){
|
|
|
+ DB::rollBack();
|
|
|
+ return [false,$exception->getMessage()];
|
|
|
+ }
|
|
|
+
|
|
|
+ return [true, ''];
|
|
|
+ }
|
|
|
+
|
|
|
+ private function saveDetailDaily($id, $time, $data){
|
|
|
+ if(! empty($data['details'])){
|
|
|
+ $unit = [];
|
|
|
+ foreach ($data['details'] as $value){
|
|
|
+ $unit[] = [
|
|
|
+ 'main_id' => $id,
|
|
|
+ 'employee_id' => $value['employee_id'],
|
|
|
+ 'start_time_hour' => $value['start_time_hour'],
|
|
|
+ 'start_time_min' => $value['start_time_min'],
|
|
|
+ 'end_time_hour' => $value['end_time_hour'],
|
|
|
+ 'end_time_min' => $value['end_time_min'],
|
|
|
+ 'total_work_min' => $value['total_work_min'],
|
|
|
+ 'crt_time' => $time,
|
|
|
+ 'top_depart_id' => $value['top_depart_id'],
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ if(! empty($unit)) DailyPwOrderDetails::insert($unit);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private function getDetailDaily($id){
|
|
|
+ $data = DailyPwOrderDetails::where('del_time',0)
|
|
|
+ ->where('main_id', $id)
|
|
|
+ ->select('employee_id', 'start_time_hour', 'start_time_min', 'end_time_hour', 'end_time_min', 'total_work_min')
|
|
|
+ ->get()->toArray();
|
|
|
+
|
|
|
+ $id = array_column($data,'employee_id');
|
|
|
+ $map = Employee::whereIn('id', $id)->select('title','id','number')->get()->toArray();
|
|
|
+ $map = array_column($map,null,'id');
|
|
|
+
|
|
|
+ foreach ($data as $key => $value){
|
|
|
+ $tmp = $map[$value['employee_id']] ?? [];
|
|
|
+ $merge = [];
|
|
|
+ $merge['employee_title'] = $tmp['title'];
|
|
|
+ $merge['employee_number'] = $tmp['number'];
|
|
|
+ $data[$key] = array_merge($value, $merge);
|
|
|
+ }
|
|
|
+
|
|
|
+ $detail = [
|
|
|
+ 'details' => $data,
|
|
|
+ ];
|
|
|
+
|
|
|
+ foreach ($detail as $key => $value) {
|
|
|
+ if (empty($value)) {
|
|
|
+ $detail[$key] = (object)[]; // 转成 stdClass 对象
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return $detail;
|
|
|
+ }
|
|
|
+
|
|
|
+ public function dailyPwOrderDel($data){
|
|
|
+ if($this->isEmpty($data,'id')) return [false,'请选择数据!'];
|
|
|
+
|
|
|
+ try {
|
|
|
+ DB::beginTransaction();
|
|
|
+ $time = time();
|
|
|
+
|
|
|
+ DailyPwOrder::where('del_time',0)
|
|
|
+ ->whereIn('id',$data['id'])
|
|
|
+ ->update(['del_time' => $time]);
|
|
|
+
|
|
|
+ DailyPwOrderDetails::where('del_time',0)
|
|
|
+ ->whereIn('main_id', $data['id'])
|
|
|
+ ->update(['del_time' => $time]);
|
|
|
+
|
|
|
+ DB::commit();
|
|
|
+ }catch (\Exception $exception){
|
|
|
+ DB::rollBack();
|
|
|
+ return [false,$exception->getMessage()];
|
|
|
+ }
|
|
|
+
|
|
|
+ return [true, ''];
|
|
|
+ }
|
|
|
+
|
|
|
+ public function dailyPwOrderDetail($data, $user){
|
|
|
+ if($this->isEmpty($data,'id')) return [false,'请选择数据!'];
|
|
|
+ $customer = DailyPwOrder::where('del_time',0)
|
|
|
+ ->where('id',$data['id'])
|
|
|
+ ->first();
|
|
|
+ if(empty($customer)) return [false,'人员日工时单不存在或已被删除'];
|
|
|
+ $customer = $customer->toArray();
|
|
|
+ $customer['crt_name'] = Employee::where('id',$customer['crt_id'])->value('title');
|
|
|
+ $customer['crt_time'] = $customer['crt_time'] ? date("Y-m-d H:i:s",$customer['crt_time']): '';
|
|
|
+ $item = Item::where('id', $customer['item_id'])->first();
|
|
|
+ $customer['item_title'] = $item->title;
|
|
|
+ $customer['item_code'] = $item->code;
|
|
|
+ $customer['month'] = $customer['month'] ? date("Y-m",$customer['month']): '';
|
|
|
+
|
|
|
+ $details = $this->getDetailDaily($data['id']);
|
|
|
+ $customer = array_merge($customer, $details);
|
|
|
+
|
|
|
+ return [true, $customer];
|
|
|
+ }
|
|
|
+
|
|
|
+ public function dailyPwOrderCommon($data,$user, $field = []){
|
|
|
+ if(empty($field)) $field = DailyPwOrder::$field;
|
|
|
+
|
|
|
+ $model = DailyPwOrder::Clear($user,$data);
|
|
|
+ $model = $model->where('del_time',0)
|
|
|
+ ->select($field)
|
|
|
+ ->orderby('id', 'desc');
|
|
|
+
|
|
|
+ if(! empty($data['code'])) $model->where('code', 'LIKE', '%'.$data['code'].'%');
|
|
|
+ if(! empty($data['id'])) $model->whereIn('id', $data['id']);
|
|
|
+ if(! empty($data['crt_time'][0]) && ! empty($data['crt_time'][1])) {
|
|
|
+ $return = $this->changeDateToTimeStampAboutRange($data['crt_time']);
|
|
|
+ $model->where('crt_time','>=',$return[0]);
|
|
|
+ $model->where('crt_time','<=',$return[1]);
|
|
|
+ }
|
|
|
+
|
|
|
+ return $model;
|
|
|
+ }
|
|
|
+
|
|
|
+ public function dailyPwOrderList($data,$user){
|
|
|
+ $model = $this->dailyPwOrderCommon($data, $user);
|
|
|
+ $list = $this->limit($model,'',$data);
|
|
|
+ $list = $this->fillDataDaily($list);
|
|
|
+
|
|
|
+ return [true, $list];
|
|
|
+ }
|
|
|
+
|
|
|
+ public function dailyPwOrderRule(&$data, $user, $is_add = true){
|
|
|
+ if(empty($data['order_time'])) return [false, '单据日期不能为空'];
|
|
|
+ $data['order_time'] = $this->changeDateToDate($data['order_time']);
|
|
|
+ if(empty($data['item_id'])) return [false, '项目不能为空'];
|
|
|
+ $bool = Item::where('del_time',0)->where('id', $data['item_id'])->exists();
|
|
|
+ if(! $bool) return [false, '项目不存在或已被删除'];
|
|
|
+
|
|
|
+ $data['top_depart_id'] = $user['top_depart_id'];
|
|
|
+ if(empty($data['details'])) return [false, '人员日工时单明细不能为空'];
|
|
|
+ foreach ($data['details'] as $key => $value){
|
|
|
+ if(empty($value['employee_id'])) return [false, '人员不能为空'];
|
|
|
+ if(empty($data['item_id'])) return [false,'项目不能为空'];
|
|
|
+ $res = $this->checkNumber($data['start_time_hour'],0,'non-negative');
|
|
|
+ if(! $res['valid']) return [false,'研发时段开始点:' . $res['error']];
|
|
|
+ $res = $this->checkNumber($data['start_time_min'],0,'non-negative');
|
|
|
+ if(! $res['valid']) return [false,'研发时段开始分:' . $res['error']];
|
|
|
+ $res = $this->checkNumber($data['end_time_hour'],0,'non-negative');
|
|
|
+ if(! $res['valid']) return [false,'研发时段结束点:' . $res['error']];
|
|
|
+ $res = $this->checkNumber($data['end_time_hour'],0,'non-negative');
|
|
|
+ if(! $res['valid']) return [false,'研发时段结束分:' . $res['error']];
|
|
|
+ $res = $this->checkNumber($data['total_work_min'],2,'positive');
|
|
|
+ if(! $res['valid']) return [false,'研发合计工时(分):' . $res['error']];
|
|
|
+ $data['details'][$key]['top_depart_id'] = $data['top_depart_id'];
|
|
|
+ }
|
|
|
+
|
|
|
+ if($is_add){
|
|
|
+
|
|
|
+ }else{
|
|
|
+ if(empty($data['id'])) return [false,'ID不能为空'];
|
|
|
+ $bool = DailyPwOrder::where('top_depart_id', $data['top_depart_id'])
|
|
|
+ ->where('id',$data['id'])
|
|
|
+ ->where('del_time',0)
|
|
|
+ ->exists();
|
|
|
+ if(! $bool) return [false, '人员日工时单不存在或已被删除'];
|
|
|
+ }
|
|
|
+
|
|
|
+ return [true, ''];
|
|
|
+ }
|
|
|
+
|
|
|
+ public function fillDataDaily($data){
|
|
|
+ if(empty($data['data'])) return $data;
|
|
|
+
|
|
|
+ $emp = (new EmployeeService())->getEmployeeMap(array_unique(array_column($data['data'],'crt_id')));
|
|
|
+ $item = (new ItemService())->getItemMap(array_unique(array_column($data['data'],'item_id')));
|
|
|
+ foreach ($data['data'] as $key => $value){
|
|
|
+ $data['data'][$key]['crt_time'] = $value['crt_time'] ? date('Y-m-d H:i:s',$value['crt_time']) : '';
|
|
|
+ $data['data'][$key]['order_time'] = $value['order_time'] ? date('Y-m-d',$value['order_time']) : '';
|
|
|
+ $data['data'][$key]['crt_name'] = $emp[$value['crt_id']] ?? '';
|
|
|
+ $item_tmp = $item[$value['item_id']] ?? [];
|
|
|
+ $data['data'][$key]['item_title'] = $item_tmp['title'] ?? '';
|
|
|
+ $data['data'][$key]['item_code'] = $item_tmp['code'] ?? '';
|
|
|
+ }
|
|
|
+
|
|
|
+ return $data;
|
|
|
+ }
|
|
|
+
|
|
|
+ public function fillDataForExportDaily($data, $column, &$return)
|
|
|
+ {
|
|
|
+ if (empty($data)) return;
|
|
|
+
|
|
|
+ $mainIds = array_column($data, 'id');
|
|
|
+ // 1. 获取详情及所有关联档案(项目、人员)的映射
|
|
|
+ $detailsMap = $this->getDailyDetailsMap($mainIds, $data);
|
|
|
+
|
|
|
+ foreach ($data as $main) {
|
|
|
+ $mainId = $main['id'];
|
|
|
+ $details = $detailsMap[$mainId] ?? [];
|
|
|
+
|
|
|
+ // 2. 提取并格式化主表共有信息
|
|
|
+ $mainInfo = [
|
|
|
+ 'code' => $main['code'],
|
|
|
+ 'order_time' => !empty($main['order_time']) ? date('Y-m-d', $main['order_time']) : '',
|
|
|
+ ];
|
|
|
+
|
|
|
+ if (empty($details)) {
|
|
|
+ // 无明细时只导出一行主表信息
|
|
|
+ $tempRow = [];
|
|
|
+ foreach ($column as $col) {
|
|
|
+ $tempRow[] = $mainInfo[$col] ?? '';
|
|
|
+ }
|
|
|
+ $return[] = $tempRow;
|
|
|
+ } else {
|
|
|
+ // 3. 平铺:将详情里的项目信息、人员信息与主表信息合并
|
|
|
+ foreach ($details as $sub) {
|
|
|
+ $fullRowData = array_merge($mainInfo, $sub);
|
|
|
+ $tempRow = [];
|
|
|
+ foreach ($column as $col) {
|
|
|
+ $tempRow[] = $fullRowData[$col] ?? '';
|
|
|
+ }
|
|
|
+ $return[] = $tempRow;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public function getDailyDetailsMap($mainIds, $mainData)
|
|
|
+ {
|
|
|
+ // 1. 获取所有子表记录
|
|
|
+ $details = DB::table('daily_pw_order_details')
|
|
|
+ ->where('del_time', 0)
|
|
|
+ ->whereIn('main_id', $mainIds)
|
|
|
+ ->get();
|
|
|
+
|
|
|
+ // 2. 提取所有关联 ID
|
|
|
+ $empIds = $details->pluck('employee_id')->unique();
|
|
|
+ $itemIds = array_unique(array_column($mainData, 'item_id')); // 从主表数组提取项目ID
|
|
|
+
|
|
|
+ // 3. 批量获取档案 Map
|
|
|
+ $empMap = DB::table('employee')
|
|
|
+ ->whereIn('id', $empIds)
|
|
|
+ ->get(['id', 'title', 'number'])
|
|
|
+ ->keyBy('id');
|
|
|
+
|
|
|
+ $itemMap = DB::table('item')
|
|
|
+ ->whereIn('id', $itemIds)
|
|
|
+ ->get(['id', 'title', 'code'])
|
|
|
+ ->keyBy('id');
|
|
|
+
|
|
|
+ // 4. 将主表的项目信息预先挂载到主表 ID 下,方便后续合并
|
|
|
+ $mainItemInfo = [];
|
|
|
+ foreach ($mainData as $m) {
|
|
|
+ $proj = $itemMap[$m['item_id']] ?? null;
|
|
|
+ $mainItemInfo[$m['id']] = [
|
|
|
+ 'item_code' => $proj ? $proj->code : '',
|
|
|
+ 'item_title' => $proj ? $proj->title : '',
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ $res = [];
|
|
|
+ if ($details->isEmpty()) {
|
|
|
+ // 如果没有详情,把项目信息返回去,确保主表能导出行
|
|
|
+ foreach ($mainItemInfo as $mId => $info) {
|
|
|
+ $res[$mId] = [];
|
|
|
+ }
|
|
|
+ return $res;
|
|
|
+ }
|
|
|
+
|
|
|
+ foreach ($details as $item) {
|
|
|
+ $emp = $empMap[$item->employee_id] ?? null;
|
|
|
+
|
|
|
+ // 组装明细行数据
|
|
|
+ $detailRow = [
|
|
|
+ // 人员信息
|
|
|
+ 'employee_number' => $emp ? $emp->number : '',
|
|
|
+ 'employee_title' => $emp ? $emp->title : '',
|
|
|
+ // 时间信息
|
|
|
+ 'start_time' => sprintf('%02d:%02d', $item->start_time_hour, $item->start_time_min),
|
|
|
+ 'end_time' => sprintf('%02d:%02d', $item->end_time_hour, $item->end_time_min),
|
|
|
+ // 将主表的项目信息也塞进每一行详情里实现平铺
|
|
|
+ 'item_code' => $mainItemInfo[$item->main_id]['item_code'] ?? '',
|
|
|
+ 'item_title' => $mainItemInfo[$item->main_id]['item_title'] ?? '',
|
|
|
+ ];
|
|
|
+
|
|
|
+ $res[$item->main_id][] = $detailRow;
|
|
|
+ }
|
|
|
+
|
|
|
+ return $res;
|
|
|
+ }
|
|
|
}
|