TalentAllowanceApi.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. <?php
  2. namespace app\common\api;
  3. use app\common\model\TalentAllowance as TaModel;
  4. use app\common\state\MainState;
  5. use think\facade\Db;
  6. use app\common\state\CommonConst;
  7. use app\common\state\AllowanceProjectEnum;
  8. use app\common\model\TalentAllowanceArrange;
  9. use app\common\model\AmountStandard as AsModel;
  10. /**
  11. * Description of TalentAllowanceApi
  12. *
  13. * @author sgq
  14. */
  15. class TalentAllowanceApi {
  16. public static function getList($params) {
  17. $user = session("user");
  18. $order = trim($params["order"]) ?: "desc";
  19. $offset = trim($params["offset"]) ?: 0;
  20. $limit = trim($params["limit"]) ?: 10;
  21. $where = [];
  22. $where[] = ["delete", "=", 0];
  23. $where[] = ["enterpriseId", "=", $user["uid"]];
  24. if ($_where = self::setTalentAllowanceInfo($params)) {
  25. $where = array_merge($where, $_where);
  26. }
  27. $count = TaModel::where($where)->count();
  28. $list = TaModel::where($where)->limit($offset, $limit)->order("year {$order},createTime {$order}")->select()->toArray();
  29. $levelList = DictApi::selectByParentCode("talent_arrange");
  30. $talentTypeList = DictApi::selectByParentCode("enterprise_tag");
  31. $streetList = DictApi::selectByParentCode("street");
  32. $identifyConditionIds = array_filter(array_unique(array_column($list, "identifyCondition")));
  33. $whr[] = ["id", "in", $identifyConditionIds];
  34. $whr[] = ["type", "=", $user["type"]];
  35. $identifyConditionKvList = TalentConditionApi::getKvList($whr);
  36. foreach ($list as $key => $item) {
  37. $list[$key]["talentArrangeName"] = $levelList[$item["talentArrange"]];
  38. $list[$key]["talentTypeName"] = $talentTypeList[$item["talentType"]];
  39. $list[$key]["addressName"] = $streetList[$item["address"]];
  40. $list[$key]["identifyConditionText"] = $identifyConditionKvList[$item["identifyCondition"]];
  41. }
  42. return ["total" => $count, "rows" => $list];
  43. }
  44. public static function setTalentAllowanceInfo($params) {
  45. $where = [];
  46. if (\StrUtil::isNotEmpAndNull($params["year"])) {
  47. $where[] = ["year", "=", $params["year"]];
  48. }
  49. if (\StrUtil::isNotEmpAndNull($params["enterpriseName"])) {
  50. $where[] = ["enterpriseName", "like", "%" . $params["enterpriseName"] . "%"];
  51. }
  52. if (\StrUtil::isNotEmpAndNull($params["name"])) {
  53. $where[] = ["name", "like", "%" . $params["name"] . "%"];
  54. }
  55. if (\StrUtil::isNotEmpAndNull($params["talentType"])) {
  56. $where[] = ["talentType", "=", $params["talentType"]];
  57. }
  58. if (\StrUtil::isNotEmpAndNull($params["talentArrange"])) {
  59. $where[] = ["talentArrange", "=", $params["talentArrange"]];
  60. }
  61. if (\StrUtil::isNotEmpAndNull($params["identiryCondition"])) {
  62. $where[] = ["identifyCondition", "=", $params["identifyCondition"]];
  63. }
  64. if (\StrUtil::isNotEmpAndNull($params["allowanceType"])) {
  65. $where[] = ["allowanceType", "=", $params["allowanceType"]];
  66. }
  67. if (\StrUtil::isNotEmpAndNull($params["address"])) {
  68. $where[] = ["address", "=", $params["address"]];
  69. }
  70. return $where;
  71. }
  72. public static function getInfoById($id) {
  73. return TaModel::findOrEmpty($id)->toArray();
  74. }
  75. public static function getApplyCountByIdCard($idCard) {
  76. $where = [];
  77. $where[] = ["idCard", "=", $idCard];
  78. $where[] = ["checkState", "<>", MainState::NOTPASS];
  79. $list = TaModel::where($where)->distinct(true)->field("substr(year,1,4) as year")->select()->toArray();
  80. $years = array_column($list, "year");
  81. return $years;
  82. }
  83. public static function getPassYearsByIdCard($idCard) {
  84. $where = [];
  85. $where[] = ["idCard", "=", $idCard];
  86. $where[] = ["checkState", "=", MainState::PASS];
  87. $list = TaModel::where($where)->distinct(true)->field("substr(year,1,4) as year")->select()->toArray();
  88. $passYears = array_column($list, "year");
  89. return $passYears;
  90. }
  91. public static function validateAllowanceType($id) {
  92. $info = ["id" => $id];
  93. $old = self::getInfoById($id);
  94. $info["type"] = $old["type"];
  95. $info["allowanceType"] = $old["allowanceType"];
  96. $enterpriseMap = \app\common\model\Enterprise::where("type", $old["type"])->column("name", "id");
  97. /* * 查询工作单位记录 */
  98. $initDetailList = \app\common\model\TalentAllowancecontractDetail::where("mainId", $info["id"])->select()->toArray();
  99. $detaiPdList = []; //用于判定类型
  100. $detailMonthList = []; //用于计算月份
  101. foreach ($initDetailList as $detail) {
  102. $projectList = \app\common\model\TalentAllowanceProject::where("baseId", $detail["id"])->select()->toArray();
  103. $projectMap = [];
  104. foreach ($projectList as $project) {
  105. $projectMap[$project["project"]] = $project;
  106. }
  107. $detail["list"] = $projectList;
  108. $detail["projectMap"] = $projectMap;
  109. $detail["enterpriseName"] = $enterpriseMap[$detail["enterpriseId"]];
  110. /* * 筛选符合条件的人才标签 */
  111. $detaiPdList[] = $detail;
  112. $detailMonthList[] = $detail;
  113. }
  114. $monthMap = self::mergeMonth($detailMonthList);
  115. $monthAndDayMap = self::mergeMonthNeedDay($detailMonthList);
  116. $info["recommendAllowanceType"] = 1;
  117. $info["recommendAllowanceMsg"] = [];
  118. $projectList = \app\common\model\TalentAllowanceProject::where("mainId", $id)->select()->toArray();
  119. $set = self::valideAllowanceType($info, $projectList, $monthMap, $monthAndDayMap);
  120. $info["recommendAllowanceMsg"][] = "综合以上所有判断得到最终补贴类型为:";
  121. if ($info["recommendAllowanceType"] == 1) {
  122. $info["recommendAllowanceMsg"][] = "<span style='color:red;font-weight:bold;'>工作津贴</span>;";
  123. $info["recommendAllowanceMsg"][] = "可享受月份为:";
  124. $info["recommendAllowanceMsg"][] = "<span style='color:red;font-weight:bold;'>" . implode(",", $set) . "</span>;";
  125. }
  126. if ($info["recommendAllowanceType"] == 2)
  127. $info["recommendAllowanceMsg"][] = "<span style='color:red;font-weight:bold;'>一次性交通补贴</span>;";
  128. if ($info["recommendAllowanceType"] == 3)
  129. $info["recommendAllowanceMsg"][] = "<span style='color:red;font-weight:bold;'>不予兑现</span>;";
  130. usort($set, function($a, $b) {
  131. return (int) $a - (int) $b;
  132. });
  133. $info["recommendMonths"] = implode(",", $set);
  134. self::calculateAllowance($info, $set, $detailMonthList);
  135. return $info;
  136. }
  137. /**
  138. * 集成电路津补贴总校验
  139. * */
  140. private static function valideAllowanceType(&$info, $projectList, $monthMap, $monthAndDayMap) {
  141. $set = ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"];
  142. /* * 2.判定工作月份、五险和个税是否满足重叠6个月要求* */
  143. $workdaySet = self::chkMonths($monthMap[AllowanceProjectEnum::PROJECT_ATTENDANCE], $info, "上年度工作月份", "①");
  144. $pensionSet = self::chkMonths($monthMap[AllowanceProjectEnum::PROJECT_SB_PENSION], $info, "养老保险", "②");
  145. $unemploymentSet = self::chkMonths($monthMap[AllowanceProjectEnum::PROJECT_SB_UNEMPLOYMENT], $info, "失业保险", "③");
  146. $medicaSet = self::chkMonths($monthMap[AllowanceProjectEnum::PROJECT_SB_MEDICA], $info, "医疗保险", "④");
  147. $taxSet = self::chkMonths($monthMap[AllowanceProjectEnum::PROJECT_TAX], $info, "个税", "⑤");
  148. $set = array_intersect($set, $workdaySet);
  149. $set = array_intersect($set, $pensionSet);
  150. $set = array_intersect($set, $unemploymentSet);
  151. $set = array_intersect($set, $medicaSet);
  152. $set = array_intersect($set, $taxSet);
  153. usort($set, function($a, $b) {
  154. return (int) $a - (int) $b;
  155. });
  156. if ($info["recommendAllowanceType"] == 1) {
  157. if (count($set) < 6) {
  158. //如果全部满足6个月,但是重叠时间不满足6个月,开始检测是否符合交通补贴要求
  159. $info["recommendAllowanceType"] = 2;
  160. $info["recommendAllowanceMsg"][] = "社会保险、个税、上年度工作月份交集月份不满足6个月(" . implode(",", $set) . "),无法享受工作津贴(×)";
  161. } else {
  162. //检查连续缴纳月份是否满足6个月
  163. $count = 1;
  164. foreach ($set as $s) {
  165. $currentVal = intval($s);
  166. $nextVal = $currentVal + 1;
  167. $nextKey = str_pad($nextVal, 2, "0", STR_PAD_LEFT);
  168. if (in_array($nextKey, $set)) {
  169. $count++;
  170. if ($count >= 6) {
  171. break;
  172. }
  173. } else {
  174. $count = 1;
  175. }
  176. }
  177. if ($count < 6) {
  178. $info["recommendAllowanceType"] = 2;
  179. $info["recommendAllowanceMsg"][] = "社会保险、个税、上年度工作月份交集月份不满足连续缴纳6个月(" . implode(",", $set) . "),无法享受工作津贴(×)";
  180. }
  181. }
  182. }
  183. if ($info["recommendAllowanceType"] == 2) {
  184. //判断境内工作时间是否大于30天
  185. if ($info["allowanceType"] == 2) {
  186. $totalDays = 0;
  187. $workmonths = $monthAndDayMap[AllowanceProjectEnum::PROJECT_ATTENDANCE];
  188. foreach ($workmonths as $days) {
  189. $totalDays += $days;
  190. }
  191. if ($totalDays < 30) {
  192. $info["recommendAllowanceType"] = 3;
  193. $info["recommendAllowanceMsg"][] = "全年在我市工作仅{$totalDays}天,未达到30天,无法享受一次性交通津贴(×)";
  194. }
  195. } else {
  196. if (count($workdaySet) == 0) {
  197. $info["recommendAllowanceType"] = 3;
  198. $info["recommendAllowanceMsg"][] = "全年在我市工作未达到30天,无法享受一次性交通津贴(×)";
  199. } else {
  200. $info["recommendAllowanceType"] = 2;
  201. $info["recommendAllowanceMsg"][] = "*首选为工作津贴,未录入实际工作天数,需要进一步核实提交的相关附件是否满足全年在我市工作30天";
  202. }
  203. }
  204. }
  205. return $set;
  206. }
  207. /**
  208. * 计算津补贴
  209. */
  210. private static function calculateAllowance(&$info, $retainMonths, $detailMonthList) {
  211. /* * 查询人才层次变更记录 */
  212. $arrangeList = TalentAllowanceArrange::where("mainId", $info["id"])->order("talentArrange")->select()->toArray();
  213. foreach ($arrangeList as &$arrange) {
  214. $where = [];
  215. $where[] = ["type", "=", $info["type"]];
  216. $where[] = ["allowanceType", "in", [1, 2]];
  217. $where[] = ["talentArrange", "=", $arrange["talentArrange"]];
  218. $list = AsModel::where($where)->field("money,allowanceType")->select()->toArray();
  219. foreach ($list as $amount) {
  220. if ($amount["allowanceType"] == 1) {
  221. $arrange["jobMoney"] = $amount["money"];
  222. }
  223. if ($amount["allowanceType"] == 2) {
  224. $arrange["jtMoney"] = $amount["money"];
  225. }
  226. }
  227. }unset($arrange);
  228. /* * * 容器 */
  229. $jobMoney = 0.00; //计算所得工作津贴
  230. $jtMoney = 0.00; //计算所得一次性交通补贴
  231. $recommendMonths = []; //推荐月份
  232. $talentArrange = null;
  233. /* * *********计算************* */
  234. $msgBulider = [];
  235. switch ($info["recommendAllowanceType"]) {
  236. case 1:
  237. foreach ($arrangeList as &$arrange) {
  238. if (\StrUtil::isNotEmpAndNull($arrange["prepareMonths"])) {
  239. $levelList = array_filter(explode(",", $arrange["prepareMonths"]));
  240. $levelList = array_intersect($levelList, $retainMonths);
  241. $total = round($arrange["jobMoney"] * count($levelList), 2);
  242. $jobMoney += $total;
  243. $msgBulider[] = sprintf("%d(%s)x%s(第%d层次)", count($levelList), $levelList ? implode(",", $levelList) : "", $arrange["jobMoney"], $arrange["talentArrange"]);
  244. $recommendMonths = array_merge($recommendMonths, $levelList);
  245. usort($recommendMonths, function($a, $b) {
  246. return (int) $a - (int) $b;
  247. });
  248. $arrange["months"] = implode(",", $levelList);
  249. $arrange["count"] = count($levelList);
  250. $arrange["total"] = $total;
  251. } else {
  252. $msgBulider[] = sprintf("0()x%s(第%d层次)", $arrange["jobMoney"], $arrange["talentArrange"]);
  253. $arrange["count"] = 0;
  254. $arrange["total"] = 0.00;
  255. }
  256. }unset($arrange);
  257. $info["recommendMonths"] = implode(",", $recommendMonths);
  258. $info["recommendAllowanceMsg"][] = "通过与人才证书有效期取交集得到最终可享受月份:";
  259. $info["recommendAllowanceMsg"][] = "<span style='color:red;font-weight:bold;'>" . implode(",", $recommendMonths) . "</span>;";
  260. $info["recommendAllowanceMsg"][] = "经过计算:人才津贴为<span style='color:red;font-weight:bold;'>" . $jobMoney . "</span>;";
  261. $info["recommendMoney"] = $jobMoney;
  262. $info["recommendMoneyDesc"] = implode("+", $msgBulider);
  263. break;
  264. case 2:
  265. foreach ($arrangeList as $arrange) {
  266. $jtMoney = $arrange["jtMoney"];
  267. $talentArrange = $arrange["talentArrange"];
  268. }
  269. $info["recommendMoney"] = $jtMoney;
  270. $info["recommendMonths"] = "";
  271. $info["recommendMoneyDesc"] = "一次性交通补贴";
  272. $info["workAllowanceMoney"] = 0.00;
  273. $info["developAllowanceMoney"] = 0.00;
  274. $info["recommendTalentArrange"] = $talentArrange;
  275. break;
  276. case 3:
  277. $info["recommendMoney"] = 0.00;
  278. $info["recommendMonths"] = "";
  279. $info["recommendMoneyDesc"] = "不予兑现";
  280. $info["workAllowanceMoney"] = 0.00;
  281. $info["developAllowanceMoney"] = 0.00;
  282. break;
  283. }
  284. return $arrangeList;
  285. }
  286. /**
  287. * 判定是否交足6个月(集成电路)
  288. * @param set
  289. * @param info
  290. * @param name
  291. */
  292. private static function chkMonths($set, &$info, $name, $sort) {
  293. if ($name == "上年度工作月份") {
  294. if ($info["allowanceType"] == 2) {
  295. $tmp = [];
  296. foreach ($set as $s) {
  297. $_s = explode("=", $s);
  298. $month = $_s[0];
  299. $days = $_s[1];
  300. if ($days > 0) {
  301. $tmp[] = $month;
  302. }
  303. }
  304. $set = $tmp;
  305. }
  306. }
  307. if ($info["recommendAllowanceType"] == 1 && (!$set || count($set) < 6)) {
  308. $info["recommendAllowanceType"] = 2;
  309. $info["recommendAllowanceMsg"][] = $sort . $name . "不足6个月,无法享受工作津贴(×)";
  310. }
  311. return $set;
  312. }
  313. //合并所有项目的月份
  314. private static function mergeMonth($detailList) {
  315. $taxList = [];
  316. $wagesList = [];
  317. $pensionList = [];
  318. $unemploymentList = [];
  319. $medicaList = [];
  320. $attendanceList = [];
  321. $workdayList = [];
  322. foreach ($detailList as $detail) {
  323. $projectMap = $detail["projectMap"];
  324. if ($projectMap[AllowanceProjectEnum::PROJECT_TAX] && \StrUtil::isNotEmpAndNull($projectMap[AllowanceProjectEnum::PROJECT_TAX]["months"])) {
  325. $tmp = array_filter(explode(",", $projectMap[AllowanceProjectEnum::PROJECT_TAX]["months"]));
  326. $taxList = array_merge($taxList, $tmp);
  327. }
  328. if ($projectMap[AllowanceProjectEnum::PROJECT_WAGES] && \StrUtil::isNotEmpAndNull($projectMap[AllowanceProjectEnum::PROJECT_WAGES]["months"])) {
  329. $tmp = array_filter(explode(",", $projectMap[AllowanceProjectEnum::PROJECT_WAGES]["months"]));
  330. $wagesList = array_merge($wagesList, $tmp);
  331. }
  332. if ($projectMap[AllowanceProjectEnum::PROJECT_SB_PENSION] && \StrUtil::isNotEmpAndNull($projectMap[AllowanceProjectEnum::PROJECT_SB_PENSION]["months"])) {
  333. $tmp = array_filter(explode(",", $projectMap[AllowanceProjectEnum::PROJECT_SB_PENSION]["months"]));
  334. $pensionList = array_merge($pensionList, $tmp);
  335. }
  336. if ($projectMap[AllowanceProjectEnum::PROJECT_SB_UNEMPLOYMENT] && \StrUtil::isNotEmpAndNull($projectMap[AllowanceProjectEnum::PROJECT_SB_UNEMPLOYMENT]["months"])) {
  337. $tmp = array_filter(explode(",", $projectMap[AllowanceProjectEnum::PROJECT_SB_UNEMPLOYMENT]["months"]));
  338. $unemploymentList = array_merge($unemploymentList, $tmp);
  339. }
  340. if ($projectMap[AllowanceProjectEnum::PROJECT_SB_MEDICA] && \StrUtil::isNotEmpAndNull($projectMap[AllowanceProjectEnum::PROJECT_SB_MEDICA]["months"])) {
  341. $tmp = array_filter(explode(",", $projectMap[AllowanceProjectEnum::PROJECT_SB_MEDICA]["months"]));
  342. $medicaList = array_merge($medicaList, $tmp);
  343. }
  344. if ($projectMap[AllowanceProjectEnum::PROJECT_ATTENDANCE] && \StrUtil::isNotEmpAndNull($projectMap[AllowanceProjectEnum::PROJECT_ATTENDANCE]["months"])) {
  345. $tmp = array_filter(explode(",", $projectMap[AllowanceProjectEnum::PROJECT_ATTENDANCE]["months"]));
  346. $attendanceList = array_merge($attendanceList, $tmp);
  347. }
  348. if ($projectMap[AllowanceProjectEnum::PROJECT_WORKDAY] && \StrUtil::isNotEmpAndNull($projectMap[AllowanceProjectEnum::PROJECT_WORKDAY]["months"])) {
  349. $tmp = array_filter(explode(",", $projectMap[AllowanceProjectEnum::PROJECT_WORKDAY]["months"]));
  350. $workdayList = array_merge($workdayList, $tmp);
  351. }
  352. }
  353. $map = [
  354. AllowanceProjectEnum::PROJECT_TAX => $taxList,
  355. AllowanceProjectEnum::PROJECT_WAGES => $wagesList,
  356. AllowanceProjectEnum::PROJECT_SB_PENSION => $pensionList,
  357. AllowanceProjectEnum::PROJECT_SB_UNEMPLOYMENT => $unemploymentList,
  358. AllowanceProjectEnum::PROJECT_SB_MEDICA => $medicaList,
  359. AllowanceProjectEnum::PROJECT_ATTENDANCE => $attendanceList,
  360. AllowanceProjectEnum::PROJECT_WORKDAY => $workdayList,
  361. ];
  362. return $map;
  363. }
  364. /**
  365. * 合并多个单位带有天数的项目的月份如考勤1月30天,
  366. * */
  367. private static function mergeMonthNeedDay($detailList) {
  368. $attendMap = [];
  369. $workDayMap = [];
  370. foreach ($detailList as $detail) {
  371. $attendMap = self::getMergeMonthNeedDayMap($detail["projectMap"][AllowanceProjectEnum::PROJECT_ATTENDANCE], $attendMap);
  372. $workDayMap = self::getMergeMonthNeedDayMap($detail["projectMap"][AllowanceProjectEnum::PROJECT_WORKDAY], $workDayMap);
  373. }
  374. $res = [
  375. AllowanceProjectEnum::PROJECT_ATTENDANCE => $attendMap,
  376. AllowanceProjectEnum::PROJECT_WORKDAY => $workDayMap
  377. ];
  378. return $res;
  379. }
  380. private static function getMergeMonthNeedDayMap($project, $map) {
  381. if (\StrUtil::isNotEmpAndNull($project["months"])) {
  382. $monthAndDayList = array_filter(explode(",", $project["months"]));
  383. for ($i = 0; $i < count($monthAndDayList); $i++) {
  384. $obj = explode("=", $monthAndDayList[$i]);
  385. $month = $obj[0];
  386. $day = $obj[1];
  387. $count = $map[$month];
  388. if ($count == 0) {
  389. $map[$month] = $day;
  390. } else {
  391. $map[$month] = $day + $count;
  392. }
  393. }
  394. }
  395. return $map;
  396. }
  397. }