NoField.py 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718
  1. # coding:utf-8
  2. from tables import CatchContentObject, fsc
  3. from util.sensitive_word import AcAutomation
  4. from docs.config import amount_config
  5. from docs.config import budget_config
  6. from docs.config import DEBUG
  7. from docs.config import abnormal_config
  8. import csv
  9. class NoFieldChecker(object):
  10. """
  11. 无字段或空值检查
  12. """
  13. def __init__(self):
  14. self.errors_tables = {
  15. "title": self.check_title,
  16. "projectname": self.check_projectname,
  17. "buyer":self.check_buyer,
  18. "s_winner": self.check_winner,
  19. "owner":self.check_owner,
  20. "budget": self.check_budget,
  21. "bidamount": self.check_bidamount,
  22. "area":self.check_region,
  23. "city":self.check_city,
  24. "district": self.check_district,
  25. "projectcode": self.check_projectcode,
  26. "toptype":self.check_toptype,
  27. "subtype":self.check_subtype,
  28. "publishtime":self.check_publishtime,
  29. "multipackage":self.check_subpackage,
  30. "purchasinglist":self.check_purchasinglist,
  31. "detail":self.check_detail,
  32. "href":self.check_href,
  33. "est_purchase_time":self.check_est_purchase_time,
  34. "docstarttime":self.check_docstarttime,
  35. "docendtime":self.check_docendtime,
  36. "bidstarttime":self.check_bidstarttime,
  37. "bidendtime":self.check_bidendtime,
  38. "bidopentime":self.check_bidopentime,
  39. "bidway":self.check_bidway,
  40. "buyerperson":self.check_buyerperson,
  41. "buyertel":self.check_buyertel,
  42. "agency":self.check_agency,
  43. "agencyperson":self.check_agencyperson,
  44. "agencytel":self.check_agencytel,
  45. "winnerperson":self.check_winnerperson,
  46. "winnertel":self.check_winnertel,
  47. "entname":self.check_entname,
  48. "sortstr":self.check_sort,
  49. "price":self.check_price,
  50. "winnerorder":self.check_winnerorder,
  51. "note":self.check_note,
  52. "publish_org":self.check_publish_org,
  53. "projectinfo":self.check_projectinfo,
  54. "capital":self.check_capital,
  55. "project_stage_code":self.check_project_stage,
  56. "procure_content":self.check_procure_content,
  57. "kpi": self.check_kpi,
  58. "institution": self.check_institution,
  59. "project_domain": self.check_project_domain,
  60. "project_owner": self.check_project_owner,
  61. "start_date": self.check_start_date,
  62. "end_date": self.check_end_date,
  63. "operation_start_date": self.check_operation_start_date,
  64. "operation_end_date": self.check_operation_end_date,
  65. "source_income": self.check_source_income,
  66. "construction_content": self.check_construction_content,
  67. "remarks": self.check_remarks,
  68. "cost_income_percent": self.check_cost_income_percent,
  69. "coverage_multiple": self.check_coverage_multiple,
  70. "competent_department": self.check_competent_department,
  71. }
  72. def check_competent_department(self, obj, catch_content: CatchContentObject) -> bool:
  73. """
  74. :param obj:代表一个item
  75. :return:返回true 代表异常
  76. """
  77. competent_department = obj.get("competent_department", "")
  78. if not competent_department:
  79. return True
  80. return False
  81. def check_coverage_multiple(self, obj, catch_content: CatchContentObject) -> bool:
  82. """
  83. :param obj:代表一个item
  84. :return:返回true 代表异常
  85. """
  86. coverage_multiple = obj.get("coverage_multiple", "")
  87. if not coverage_multiple:
  88. return True
  89. return False
  90. def check_cost_income_percent(self, obj, catch_content: CatchContentObject) -> bool:
  91. """
  92. :param obj:代表一个item
  93. :return:返回true 代表异常
  94. """
  95. cost_income_percent = obj.get("cost_income_percent", "")
  96. if not cost_income_percent:
  97. return True
  98. return False
  99. def check_remarks(self, obj, catch_content: CatchContentObject) -> bool:
  100. """
  101. :param obj:代表一个item
  102. :return:返回true 代表异常
  103. """
  104. remarks = obj.get("remarks", "")
  105. if not remarks:
  106. return True
  107. return False
  108. def check_construction_content(self, obj, catch_content: CatchContentObject) -> bool:
  109. """
  110. :param obj:代表一个item
  111. :return:返回true 代表异常
  112. """
  113. construction_content = obj.get("construction_content", "")
  114. if not construction_content:
  115. return True
  116. return False
  117. def check_source_income(self, obj, catch_content: CatchContentObject) -> bool:
  118. """
  119. :param obj:代表一个item
  120. :return:返回true 代表异常
  121. """
  122. source_income = obj.get("source_income", "")
  123. if not source_income:
  124. return True
  125. return False
  126. def check_operation_end_date(self, obj, catch_content: CatchContentObject) -> bool:
  127. """
  128. :param obj:代表一个item
  129. :return:返回true 代表异常
  130. """
  131. operation_end_date = obj.get("operation_end_date", "")
  132. if not operation_end_date:
  133. return True
  134. return False
  135. def check_operation_start_date(self, obj, catch_content: CatchContentObject) -> bool:
  136. """
  137. :param obj:代表一个item
  138. :return:返回true 代表异常
  139. """
  140. operation_start_date = obj.get("operation_start_date", "")
  141. if not operation_start_date:
  142. return True
  143. return False
  144. def check_end_date(self, obj, catch_content: CatchContentObject) -> bool:
  145. """
  146. :param obj:代表一个item
  147. :return:返回true 代表异常
  148. """
  149. end_date = obj.get("end_date", "")
  150. if not end_date:
  151. return True
  152. return False
  153. def check_start_date(self, obj, catch_content: CatchContentObject) -> bool:
  154. """
  155. :param obj:代表一个item
  156. :return:返回true 代表异常
  157. """
  158. start_date = obj.get("start_date", "")
  159. if not start_date:
  160. return True
  161. return False
  162. def check_project_owner(self, obj, catch_content: CatchContentObject) -> bool:
  163. """
  164. :param obj:代表一个item
  165. :return:返回true 代表异常
  166. """
  167. project_owner = obj.get("project_owner", "")
  168. if not project_owner:
  169. return True
  170. return False
  171. def check_project_domain(self, obj, catch_content: CatchContentObject) -> bool:
  172. """
  173. :param obj:代表一个item
  174. :return:返回true 代表异常
  175. """
  176. project_domain = obj.get("project_domain", "")
  177. if not project_domain:
  178. return True
  179. return False
  180. def check_bidamount(self,obj,catch_content: CatchContentObject) -> bool:
  181. """
  182. 中标金额为空检测
  183. :param obj:代表一个item
  184. :return:返回true 代表异常
  185. """
  186. subtype = obj.get("subtype", "")
  187. if subtype in ["中标", "成交","合同","验收"]:
  188. bidamount = obj.get("bidamount")
  189. if not bidamount:
  190. return True
  191. return False
  192. def check_winner(self,obj, catch_content: CatchContentObject) -> bool:
  193. """
  194. 中标单位名称为空检测,除中标类型的标讯,其他类型标讯不检查这个字段是否为空
  195. :param obj:代表一个item
  196. :return:返回true 代表异常
  197. """
  198. subtype = obj.get("subtype", "")
  199. if subtype in ["中标", "成交", "合同", "验收"]:
  200. winner = obj.get("s_winner")
  201. if not winner:
  202. return True
  203. return False
  204. def check_buyer(self,obj,catch_content: CatchContentObject) -> bool:
  205. """
  206. 采购单位名称是否为空检测
  207. :param buyer:采购单位,多个逗号分割
  208. :param obj:代表一个item
  209. :return:返回true 代表异常
  210. """
  211. subtype = obj.get("subtype", "")
  212. if subtype not in ["拟建"]:
  213. budget = obj.get("buyer")
  214. if not budget:
  215. return True
  216. return False
  217. def check_budget(self,obj, catch_content: CatchContentObject) -> bool:
  218. """
  219. 预算为空检测
  220. :param obj:代表一个item
  221. :return:返回true 代表异常
  222. """
  223. subtype = obj.get("subtype", "")
  224. if subtype in ["招标", "邀标", "询价", "竞谈","单一","竞价","变更"]:
  225. budget = obj.get("budget")
  226. if not budget:
  227. return True
  228. return False
  229. def check_region(self,obj, catch_content: CatchContentObject) -> bool:
  230. """
  231. 省份为空检测
  232. :param obj:代表一个item
  233. :return:返回true 代表异常
  234. """
  235. area = obj.get("area")
  236. if not area:
  237. return True
  238. return False
  239. def check_city(self,obj, catch_content: CatchContentObject) -> bool:
  240. """
  241. 城市为空检测
  242. :param obj:代表一个item
  243. :return:返回true 代表异常
  244. """
  245. city = obj.get("city")
  246. if not city:
  247. return True
  248. return False
  249. def check_district(self,obj, catch_content: CatchContentObject) -> bool:
  250. """
  251. 区县为空检测
  252. :param obj:代表一个item
  253. :return:返回true 代表异常
  254. """
  255. district = obj.get("district")
  256. if not district:
  257. return True
  258. return False
  259. def check_title(self,obj, catch_content: CatchContentObject) -> bool:
  260. """
  261. :param obj:代表一个item
  262. :return:返回true 代表异常
  263. """
  264. title = obj.get("title")
  265. if not title :
  266. return True
  267. return False
  268. def check_projectname(self,obj, catch_content: CatchContentObject) -> bool:
  269. """
  270. :param obj:代表一个item
  271. :return:返回true 代表异常
  272. """
  273. projectname = obj.get("projectname")
  274. if not projectname :
  275. return True
  276. return False
  277. def check_projectcode(self,obj, catch_content: CatchContentObject) -> bool:
  278. """
  279. 项目编号为空检测
  280. :param obj:代表一个item
  281. :return:返回true 代表异常
  282. """
  283. toptype = obj.get("toptype", "")
  284. if toptype not in ["拟建","采购意向"]:
  285. projectcode = obj.get("projectcode")
  286. if not projectcode:
  287. return True
  288. return False
  289. def check_subpackage(self,obj, catch_content: CatchContentObject) -> bool:
  290. """
  291. 公司名称检测
  292. :param obj:代表一个item
  293. :return:返回true 代表异常
  294. """
  295. pass
  296. # 处理正文
  297. # 检查因素
  298. # 是否返回 0000
  299. def check_purchasinglist(self,obj, catch_content: CatchContentObject) -> bool:
  300. if not obj.get("purchasinglist"):
  301. return True
  302. return False
  303. def check_toptype(self,obj, catch_content: CatchContentObject) -> bool:
  304. """
  305. 公告一级分类检测
  306. :param obj:代表一个item
  307. :return:返回true 代表异常
  308. """
  309. if not obj.get("toptype"):
  310. return True
  311. return False
  312. def check_subtype(self,obj, catch_content: CatchContentObject) -> bool:
  313. """
  314. 公告二级分类检测
  315. :param obj:代表一个item
  316. :return:返回true 代表异常
  317. """
  318. if not obj.get("subtype"):
  319. return True
  320. return False
  321. def check_publishtime(self,obj, catch_content: CatchContentObject) -> bool:
  322. if not obj.get("publishtime"):
  323. return True
  324. return False
  325. def check_detail(self,obj, catch_content: CatchContentObject) -> bool:
  326. if not obj.get("detail"):
  327. return True
  328. return False
  329. def check_href(self,obj, catch_content: CatchContentObject) -> bool:
  330. if not obj.get("href"):
  331. return True
  332. return False
  333. def check_est_purchase_time(self, obj, catch_content: CatchContentObject) -> bool:
  334. """
  335. 预计采购时间为空检测
  336. :param obj:代表一个item
  337. :return:返回true 代表异常
  338. """
  339. if obj.get("toptype") == "预告":
  340. if not obj.get("est_purchase_time"):
  341. return True
  342. return False
  343. return False
  344. def check_docstarttime(self, obj, catch_content: CatchContentObject) -> bool:
  345. """
  346. 招标文件获取开始时间为空检测
  347. :param obj:代表一个item
  348. :return:返回true 代表异常
  349. """
  350. if obj.get("toptype") == "招标":
  351. if not obj.get("docstarttime"):
  352. return True
  353. return False
  354. return False
  355. def check_docendtime(self, obj, catch_content: CatchContentObject) -> bool:
  356. """
  357. 招标文件获取截止时间为空检测
  358. :param obj:代表一个item
  359. :return:返回true 代表异常
  360. """
  361. if obj.get("toptype") == "招标":
  362. if not obj.get("docendtime"):
  363. return True
  364. return False
  365. return False
  366. def check_bidstarttime(self, obj, catch_content: CatchContentObject) -> bool:
  367. """
  368. 投标文件递交开始时间为空检测
  369. :param obj:代表一个item
  370. :return:返回true 代表异常
  371. """
  372. if obj.get("toptype") == "招标":
  373. if not obj.get("bidstarttime"):
  374. return True
  375. return False
  376. return False
  377. def check_bidendtime(self, obj, catch_content: CatchContentObject) -> bool:
  378. """
  379. 投标截止日期为空检测
  380. :param obj:代表一个item
  381. :return:返回true 代表异常
  382. """
  383. if obj.get("toptype") == "招标":
  384. if not obj.get("bidendtime"):
  385. return True
  386. return False
  387. return False
  388. def check_bidopentime(self, obj, catch_content: CatchContentObject) -> bool:
  389. """
  390. 开标日期为空检测
  391. :param obj:代表一个item
  392. :return:返回true 代表异常
  393. """
  394. if obj.get("toptype") == "招标":
  395. if not obj.get("bidopentime"):
  396. return True
  397. return False
  398. return False
  399. def check_bidway(self, obj, catch_content: CatchContentObject) -> bool:
  400. """
  401. 投标方式为空检测
  402. :param obj:代表一个item
  403. :return:返回true 代表异常
  404. """
  405. toptype = obj.get("toptype")
  406. subtype = obj.get("subtype", "")
  407. if toptype == "招标" or subtype in ["合同", "验收"]:
  408. if not obj.get("bidway"):
  409. return True
  410. return False
  411. return False
  412. def check_buyerperson(self, obj, catch_content: CatchContentObject) -> bool:
  413. """
  414. 采购单位联系人为空检测
  415. :param obj:代表一个item
  416. :return:返回true 代表异常
  417. """
  418. toptype = obj.get("toptype")
  419. subtype = obj.get("subtype", "")
  420. if toptype =="招标" or subtype in ["中标", "成交", "合同", "验收"]:
  421. if not obj.get("buyerperson"):
  422. return True
  423. return False
  424. return False
  425. def check_buyertel(self, obj, catch_content: CatchContentObject) -> bool:
  426. """
  427. 采购单位联系电话为空检测
  428. :param obj:代表一个item
  429. :return:返回true 代表异常
  430. """
  431. toptype = obj.get("toptype")
  432. subtype = obj.get("subtype", "")
  433. if toptype =="招标" or subtype in ["中标", "成交", "合同", "验收"]:
  434. if not obj.get("buyertel"):
  435. return True
  436. return False
  437. return False
  438. def check_agency(self, obj, catch_content: CatchContentObject) -> bool:
  439. """
  440. 招标代理机构空检测
  441. :param obj:代表一个item
  442. :return:返回true 代表异常
  443. """
  444. toptype = obj.get("toptype")
  445. subtype = obj.get("subtype", "")
  446. if toptype =="招标" or subtype in ["中标", "成交", "合同", "验收"]:
  447. if not obj.get("agency"):
  448. return True
  449. return False
  450. return False
  451. def check_agencyperson(self, obj, catch_content: CatchContentObject) -> bool:
  452. """
  453. 招标代理机构联系人为空检测
  454. :param obj:代表一个item
  455. :return:返回true 代表异常
  456. """
  457. toptype = obj.get("toptype")
  458. subtype = obj.get("subtype", "")
  459. if toptype =="招标" or subtype in ["中标", "成交", "合同", "验收"]:
  460. if not obj.get("agencyperson"):
  461. return True
  462. return False
  463. return False
  464. def check_agencytel(self, obj, catch_content: CatchContentObject) -> bool:
  465. """
  466. 招标代理机构联系电话为空检测
  467. :param obj:代表一个item
  468. :return:返回true 代表异常
  469. """
  470. toptype = obj.get("toptype")
  471. subtype = obj.get("subtype", "")
  472. if toptype =="招标" or subtype in ["中标", "成交", "合同", "验收"]:
  473. if not obj.get("agencytel"):
  474. return True
  475. return False
  476. return False
  477. def check_winnerperson(self, obj, catch_content: CatchContentObject) -> bool:
  478. """
  479. 中标单位联系人为空检测
  480. :param obj:代表一个item
  481. :return:返回true 代表异常
  482. """
  483. subtype = obj.get("subtype", "")
  484. if subtype in ["中标", "成交", "合同", "验收"]:
  485. if not obj.get("winnerperson"):
  486. return True
  487. return False
  488. return False
  489. def check_winnertel(self, obj, catch_content: CatchContentObject) -> bool:
  490. """
  491. 中标单位联系电话为空检测
  492. :param obj:代表一个item
  493. :return:返回true 代表异常
  494. """
  495. subtype = obj.get("subtype", "")
  496. if subtype in ["中标", "成交", "合同", "验收"]:
  497. if not obj.get("winnertel"):
  498. return True
  499. return False
  500. return False
  501. def check_entname(self, obj, catch_content: CatchContentObject) -> bool:
  502. """
  503. 候选人名称为空检测
  504. :param obj:代表一个item
  505. :return:返回true 代表异常
  506. """
  507. subtype = obj.get("subtype", "")
  508. if subtype in ["中标", "成交"]:
  509. if "winnerorder" not in obj:
  510. return True # 如果没有winnerorder字段,视为无entname
  511. for item in obj["winnerorder"]:
  512. if "entname" in item:
  513. return False # 只要有一个entname存在,就返回False
  514. return True # 所有条目都没有entname,返回True
  515. return False
  516. def check_sort(self, obj, catch_content: CatchContentObject) -> bool:
  517. """
  518. 候选人名次为空检测
  519. :param obj:代表一个item
  520. :return:返回true 代表异常
  521. """
  522. subtype = obj.get("subtype", "")
  523. if subtype in ["中标", "成交"]:
  524. if "winnerorder" not in obj:
  525. return True # 如果没有winnerorder字段,视为无entname
  526. for item in obj["winnerorder"]:
  527. if "sort" in item or "sortstr" in item:
  528. return False # 只要有一个entname存在,就返回False
  529. return True # 所有条目都没有entname,返回True
  530. return False
  531. def check_price(self, obj, catch_content: CatchContentObject) -> bool:
  532. """
  533. 投标报价为空检测
  534. :param obj:代表一个item
  535. :return:返回true 代表异常
  536. """
  537. subtype = obj.get("subtype", "")
  538. if subtype in ["中标", "成交"]:
  539. if "winnerorder" not in obj:
  540. return True # 如果没有winnerorder字段,视为无entname
  541. for item in obj["winnerorder"]:
  542. if "price" in item :
  543. return False # 只要有一个entname存在,就返回False
  544. return True # 所有条目都没有entname,返回True
  545. return False
  546. def check_winnerorder(self, obj, catch_content: CatchContentObject) -> bool:
  547. """
  548. 候选人信息为空检测
  549. :param obj:代表一个item
  550. :return:返回true 代表异常
  551. """
  552. subtype = obj.get("subtype", "")
  553. if subtype in ["中标", "成交"]:
  554. if "winnerorder" not in obj:
  555. return True # 如果没有winnerorder字段,视为无
  556. return False
  557. def check_note(self, obj, catch_content: CatchContentObject) -> bool:
  558. """
  559. 候选人信息为空检测
  560. :param obj:代表一个item
  561. :return:返回true 代表异常
  562. """
  563. toptype = obj.get("toptype", "")
  564. if toptype == "预告" :
  565. if "note" not in obj:
  566. return True # 如果没有note字段,视为无
  567. return False
  568. def check_publish_org(self, obj, catch_content: CatchContentObject) -> bool:
  569. """
  570. 发文单位 为空检测
  571. :param obj:代表一个item
  572. :return:返回true 代表异常
  573. """
  574. publish_org = obj.get("publish_org", "")
  575. if not publish_org:
  576. return True # 如果没有note字段,视为无
  577. return False
  578. def check_projectinfo(self, obj, catch_content: CatchContentObject) -> bool:
  579. """
  580. 政策附件 为空检测
  581. :param obj:代表一个item
  582. :return:返回true 代表异常
  583. """
  584. projectinfo = obj.get("projectinfo", "")
  585. infotype = obj.get("infotype", "")
  586. if infotype == '政策':
  587. if not projectinfo:
  588. return True # 如果没有projectinfo字段,视为无
  589. return False
  590. return False
  591. def check_owner(self,obj, catch_content: CatchContentObject) -> bool:
  592. """
  593. 联通拟在建类型
  594. 业主单位名称为空检测
  595. :param obj:代表一个item
  596. :return:返回true 代表异常
  597. """
  598. owner = obj.get("owner", "")
  599. if not owner:
  600. return True
  601. return False
  602. def check_total_investment(self,obj, catch_content: CatchContentObject) -> bool:
  603. """
  604. 联通拟在建类型
  605. 投资金额(万元)为空检测
  606. :param obj:代表一个item
  607. :return:返回true 代表异常
  608. """
  609. total_investment = obj.get("total_investment", "")
  610. if not total_investment:
  611. return True
  612. return False
  613. def check_area_code(self,obj, catch_content: CatchContentObject) -> bool:
  614. """
  615. 联通拟在建类型
  616. 省份为空检测
  617. :param obj:代表一个item
  618. :return:返回true 代表异常
  619. """
  620. area_code = obj.get("area_code", "")
  621. if not area_code:
  622. return True
  623. return False
  624. def check_city_code(self, obj, catch_content: CatchContentObject) -> bool:
  625. """
  626. 联通拟在建类型
  627. 城市为空检测
  628. :param obj:代表一个item
  629. :return:返回true 代表异常
  630. """
  631. city_code = obj.get("city_code", "")
  632. if not city_code:
  633. return True
  634. return False
  635. def check_capital(self,obj, catch_content: CatchContentObject) -> bool:
  636. """
  637. 联通拟在建类型
  638. 投资金额(万元)为空检测
  639. :param obj:代表一个item
  640. :return:返回true 代表异常
  641. """
  642. capital = obj.get("capital", "")
  643. if not capital:
  644. return True
  645. return False
  646. def check_project_stage(self,obj, catch_content: CatchContentObject) -> bool:
  647. """
  648. 联通拟在建类型
  649. 项目阶段为空检测
  650. :param obj:代表一个item
  651. :return:返回true 代表异常
  652. """
  653. project_stage = obj.get("project_stage_code", "")
  654. if not project_stage:
  655. return True
  656. return False
  657. def check_procure_content(self,obj, catch_content: CatchContentObject) -> bool:
  658. """
  659. 联通预算类型
  660. 项目情况为空检测
  661. :param obj:代表一个item
  662. :return:返回true 代表异常
  663. """
  664. procure_content = obj.get("procure_content", "")
  665. if not procure_content:
  666. return True
  667. return False
  668. def check_kpi(self,obj, catch_content: CatchContentObject) -> bool:
  669. """
  670. 联通预算类型
  671. 项目目标为空检测
  672. :param obj:代表一个item
  673. :return:返回true 代表异常
  674. """
  675. kpi = obj.get("kpi", "")
  676. if not kpi:
  677. return True
  678. return False
  679. def check_institution(self,obj, catch_content: CatchContentObject) -> bool:
  680. """
  681. 联通预算类型
  682. 项目单位为空检测
  683. :param obj:代表一个item
  684. :return:返回true 代表异常
  685. """
  686. institution = obj.get("institution", "")
  687. if not institution:
  688. return True
  689. return False