NoField.py 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598
  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. }
  60. def check_bidamount(self,obj,catch_content: CatchContentObject) -> bool:
  61. """
  62. 中标金额为空检测
  63. :param obj:代表一个item
  64. :return:返回true 代表异常
  65. """
  66. subtype = obj.get("subtype", "")
  67. if subtype in ["中标", "成交","合同","验收"]:
  68. bidamount = obj.get("bidamount")
  69. if not bidamount:
  70. return True
  71. return False
  72. def check_winner(self,obj, catch_content: CatchContentObject) -> bool:
  73. """
  74. 中标单位名称为空检测,除中标类型的标讯,其他类型标讯不检查这个字段是否为空
  75. :param obj:代表一个item
  76. :return:返回true 代表异常
  77. """
  78. subtype = obj.get("subtype", "")
  79. if subtype in ["中标", "成交", "合同", "验收"]:
  80. winner = obj.get("s_winner")
  81. if not winner:
  82. return True
  83. return False
  84. def check_buyer(self,obj,catch_content: CatchContentObject) -> bool:
  85. """
  86. 采购单位名称是否为空检测
  87. :param buyer:采购单位,多个逗号分割
  88. :param obj:代表一个item
  89. :return:返回true 代表异常
  90. """
  91. subtype = obj.get("subtype", "")
  92. if subtype not in ["拟建"]:
  93. budget = obj.get("buyer")
  94. if not budget:
  95. return True
  96. return False
  97. def check_budget(self,obj, catch_content: CatchContentObject) -> bool:
  98. """
  99. 预算为空检测
  100. :param obj:代表一个item
  101. :return:返回true 代表异常
  102. """
  103. subtype = obj.get("subtype", "")
  104. if subtype in ["招标", "邀标", "询价", "竞谈","单一","竞价","变更"]:
  105. budget = obj.get("budget")
  106. if not budget:
  107. return True
  108. return False
  109. def check_region(self,obj, catch_content: CatchContentObject) -> bool:
  110. """
  111. 省份为空检测
  112. :param obj:代表一个item
  113. :return:返回true 代表异常
  114. """
  115. area = obj.get("area")
  116. if not area:
  117. return True
  118. return False
  119. def check_city(self,obj, catch_content: CatchContentObject) -> bool:
  120. """
  121. 城市为空检测
  122. :param obj:代表一个item
  123. :return:返回true 代表异常
  124. """
  125. city = obj.get("city")
  126. if not city:
  127. return True
  128. return False
  129. def check_district(self,obj, catch_content: CatchContentObject) -> bool:
  130. """
  131. 区县为空检测
  132. :param obj:代表一个item
  133. :return:返回true 代表异常
  134. """
  135. district = obj.get("district")
  136. if not district:
  137. return True
  138. return False
  139. def check_title(self,obj, catch_content: CatchContentObject) -> bool:
  140. """
  141. :param obj:代表一个item
  142. :return:返回true 代表异常
  143. """
  144. title = obj.get("title")
  145. if not title :
  146. return True
  147. return False
  148. def check_projectname(self,obj, catch_content: CatchContentObject) -> bool:
  149. """
  150. :param obj:代表一个item
  151. :return:返回true 代表异常
  152. """
  153. projectname = obj.get("projectname")
  154. if not projectname :
  155. return True
  156. return False
  157. def check_projectcode(self,obj, catch_content: CatchContentObject) -> bool:
  158. """
  159. 项目编号为空检测
  160. :param obj:代表一个item
  161. :return:返回true 代表异常
  162. """
  163. toptype = obj.get("toptype", "")
  164. if toptype not in ["拟建","采购意向"]:
  165. projectcode = obj.get("projectcode")
  166. if not projectcode:
  167. return True
  168. return False
  169. def check_subpackage(self,obj, catch_content: CatchContentObject) -> bool:
  170. """
  171. 公司名称检测
  172. :param obj:代表一个item
  173. :return:返回true 代表异常
  174. """
  175. pass
  176. # 处理正文
  177. # 检查因素
  178. # 是否返回 0000
  179. def check_purchasinglist(self,obj, catch_content: CatchContentObject) -> bool:
  180. if not obj.get("purchasinglist"):
  181. return True
  182. return False
  183. def check_toptype(self,obj, catch_content: CatchContentObject) -> bool:
  184. """
  185. 公告一级分类检测
  186. :param obj:代表一个item
  187. :return:返回true 代表异常
  188. """
  189. if not obj.get("toptype"):
  190. return True
  191. return False
  192. def check_subtype(self,obj, catch_content: CatchContentObject) -> bool:
  193. """
  194. 公告二级分类检测
  195. :param obj:代表一个item
  196. :return:返回true 代表异常
  197. """
  198. if not obj.get("subtype"):
  199. return True
  200. return False
  201. def check_publishtime(self,obj, catch_content: CatchContentObject) -> bool:
  202. if not obj.get("publishtime"):
  203. return True
  204. return False
  205. def check_detail(self,obj, catch_content: CatchContentObject) -> bool:
  206. if not obj.get("detail"):
  207. return True
  208. return False
  209. def check_href(self,obj, catch_content: CatchContentObject) -> bool:
  210. if not obj.get("href"):
  211. return True
  212. return False
  213. def check_est_purchase_time(self, obj, catch_content: CatchContentObject) -> bool:
  214. """
  215. 预计采购时间为空检测
  216. :param obj:代表一个item
  217. :return:返回true 代表异常
  218. """
  219. if obj.get("toptype") == "预告":
  220. if not obj.get("est_purchase_time"):
  221. return True
  222. return False
  223. return False
  224. def check_docstarttime(self, obj, catch_content: CatchContentObject) -> bool:
  225. """
  226. 招标文件获取开始时间为空检测
  227. :param obj:代表一个item
  228. :return:返回true 代表异常
  229. """
  230. if obj.get("toptype") == "招标":
  231. if not obj.get("docstarttime"):
  232. return True
  233. return False
  234. return False
  235. def check_docendtime(self, obj, catch_content: CatchContentObject) -> bool:
  236. """
  237. 招标文件获取截止时间为空检测
  238. :param obj:代表一个item
  239. :return:返回true 代表异常
  240. """
  241. if obj.get("toptype") == "招标":
  242. if not obj.get("docendtime"):
  243. return True
  244. return False
  245. return False
  246. def check_bidstarttime(self, obj, catch_content: CatchContentObject) -> bool:
  247. """
  248. 投标文件递交开始时间为空检测
  249. :param obj:代表一个item
  250. :return:返回true 代表异常
  251. """
  252. if obj.get("toptype") == "招标":
  253. if not obj.get("bidstarttime"):
  254. return True
  255. return False
  256. return False
  257. def check_bidendtime(self, obj, catch_content: CatchContentObject) -> bool:
  258. """
  259. 投标截止日期为空检测
  260. :param obj:代表一个item
  261. :return:返回true 代表异常
  262. """
  263. if obj.get("toptype") == "招标":
  264. if not obj.get("bidendtime"):
  265. return True
  266. return False
  267. return False
  268. def check_bidopentime(self, obj, catch_content: CatchContentObject) -> bool:
  269. """
  270. 开标日期为空检测
  271. :param obj:代表一个item
  272. :return:返回true 代表异常
  273. """
  274. if obj.get("toptype") == "招标":
  275. if not obj.get("bidopentime"):
  276. return True
  277. return False
  278. return False
  279. def check_bidway(self, obj, catch_content: CatchContentObject) -> bool:
  280. """
  281. 投标方式为空检测
  282. :param obj:代表一个item
  283. :return:返回true 代表异常
  284. """
  285. toptype = obj.get("toptype")
  286. subtype = obj.get("subtype", "")
  287. if toptype == "招标" or subtype in ["合同", "验收"]:
  288. if not obj.get("bidway"):
  289. return True
  290. return False
  291. return False
  292. def check_buyerperson(self, obj, catch_content: CatchContentObject) -> bool:
  293. """
  294. 采购单位联系人为空检测
  295. :param obj:代表一个item
  296. :return:返回true 代表异常
  297. """
  298. toptype = obj.get("toptype")
  299. subtype = obj.get("subtype", "")
  300. if toptype =="招标" or subtype in ["中标", "成交", "合同", "验收"]:
  301. if not obj.get("buyerperson"):
  302. return True
  303. return False
  304. return False
  305. def check_buyertel(self, obj, catch_content: CatchContentObject) -> bool:
  306. """
  307. 采购单位联系电话为空检测
  308. :param obj:代表一个item
  309. :return:返回true 代表异常
  310. """
  311. toptype = obj.get("toptype")
  312. subtype = obj.get("subtype", "")
  313. if toptype =="招标" or subtype in ["中标", "成交", "合同", "验收"]:
  314. if not obj.get("buyertel"):
  315. return True
  316. return False
  317. return False
  318. def check_agency(self, obj, catch_content: CatchContentObject) -> bool:
  319. """
  320. 招标代理机构空检测
  321. :param obj:代表一个item
  322. :return:返回true 代表异常
  323. """
  324. toptype = obj.get("toptype")
  325. subtype = obj.get("subtype", "")
  326. if toptype =="招标" or subtype in ["中标", "成交", "合同", "验收"]:
  327. if not obj.get("agency"):
  328. return True
  329. return False
  330. return False
  331. def check_agencyperson(self, obj, catch_content: CatchContentObject) -> bool:
  332. """
  333. 招标代理机构联系人为空检测
  334. :param obj:代表一个item
  335. :return:返回true 代表异常
  336. """
  337. toptype = obj.get("toptype")
  338. subtype = obj.get("subtype", "")
  339. if toptype =="招标" or subtype in ["中标", "成交", "合同", "验收"]:
  340. if not obj.get("agencyperson"):
  341. return True
  342. return False
  343. return False
  344. def check_agencytel(self, obj, catch_content: CatchContentObject) -> bool:
  345. """
  346. 招标代理机构联系电话为空检测
  347. :param obj:代表一个item
  348. :return:返回true 代表异常
  349. """
  350. toptype = obj.get("toptype")
  351. subtype = obj.get("subtype", "")
  352. if toptype =="招标" or subtype in ["中标", "成交", "合同", "验收"]:
  353. if not obj.get("agencytel"):
  354. return True
  355. return False
  356. return False
  357. def check_winnerperson(self, obj, catch_content: CatchContentObject) -> bool:
  358. """
  359. 中标单位联系人为空检测
  360. :param obj:代表一个item
  361. :return:返回true 代表异常
  362. """
  363. subtype = obj.get("subtype", "")
  364. if subtype in ["中标", "成交", "合同", "验收"]:
  365. if not obj.get("winnerperson"):
  366. return True
  367. return False
  368. return False
  369. def check_winnertel(self, obj, catch_content: CatchContentObject) -> bool:
  370. """
  371. 中标单位联系电话为空检测
  372. :param obj:代表一个item
  373. :return:返回true 代表异常
  374. """
  375. subtype = obj.get("subtype", "")
  376. if subtype in ["中标", "成交", "合同", "验收"]:
  377. if not obj.get("winnertel"):
  378. return True
  379. return False
  380. return False
  381. def check_entname(self, obj, catch_content: CatchContentObject) -> bool:
  382. """
  383. 候选人名称为空检测
  384. :param obj:代表一个item
  385. :return:返回true 代表异常
  386. """
  387. subtype = obj.get("subtype", "")
  388. if subtype in ["中标", "成交"]:
  389. if "winnerorder" not in obj:
  390. return True # 如果没有winnerorder字段,视为无entname
  391. for item in obj["winnerorder"]:
  392. if "entname" in item:
  393. return False # 只要有一个entname存在,就返回False
  394. return True # 所有条目都没有entname,返回True
  395. return False
  396. def check_sort(self, obj, catch_content: CatchContentObject) -> bool:
  397. """
  398. 候选人名次为空检测
  399. :param obj:代表一个item
  400. :return:返回true 代表异常
  401. """
  402. subtype = obj.get("subtype", "")
  403. if subtype in ["中标", "成交"]:
  404. if "winnerorder" not in obj:
  405. return True # 如果没有winnerorder字段,视为无entname
  406. for item in obj["winnerorder"]:
  407. if "sort" in item or "sortstr" in item:
  408. return False # 只要有一个entname存在,就返回False
  409. return True # 所有条目都没有entname,返回True
  410. return False
  411. def check_price(self, obj, catch_content: CatchContentObject) -> bool:
  412. """
  413. 投标报价为空检测
  414. :param obj:代表一个item
  415. :return:返回true 代表异常
  416. """
  417. subtype = obj.get("subtype", "")
  418. if subtype in ["中标", "成交"]:
  419. if "winnerorder" not in obj:
  420. return True # 如果没有winnerorder字段,视为无entname
  421. for item in obj["winnerorder"]:
  422. if "price" in item :
  423. return False # 只要有一个entname存在,就返回False
  424. return True # 所有条目都没有entname,返回True
  425. return False
  426. def check_winnerorder(self, obj, catch_content: CatchContentObject) -> bool:
  427. """
  428. 候选人信息为空检测
  429. :param obj:代表一个item
  430. :return:返回true 代表异常
  431. """
  432. subtype = obj.get("subtype", "")
  433. if subtype in ["中标", "成交"]:
  434. if "winnerorder" not in obj:
  435. return True # 如果没有winnerorder字段,视为无
  436. return False
  437. def check_note(self, obj, catch_content: CatchContentObject) -> bool:
  438. """
  439. 候选人信息为空检测
  440. :param obj:代表一个item
  441. :return:返回true 代表异常
  442. """
  443. toptype = obj.get("toptype", "")
  444. if toptype == "预告" :
  445. if "note" not in obj:
  446. return True # 如果没有note字段,视为无
  447. return False
  448. def check_publish_org(self, obj, catch_content: CatchContentObject) -> bool:
  449. """
  450. 发文单位 为空检测
  451. :param obj:代表一个item
  452. :return:返回true 代表异常
  453. """
  454. publish_org = obj.get("publish_org", "")
  455. if not publish_org:
  456. return True # 如果没有note字段,视为无
  457. return False
  458. def check_projectinfo(self, obj, catch_content: CatchContentObject) -> bool:
  459. """
  460. 政策附件 为空检测
  461. :param obj:代表一个item
  462. :return:返回true 代表异常
  463. """
  464. projectinfo = obj.get("projectinfo", "")
  465. infotype = obj.get("infotype", "")
  466. if infotype == '政策':
  467. if not projectinfo:
  468. return True # 如果没有projectinfo字段,视为无
  469. return False
  470. return False
  471. def check_owner(self,obj, catch_content: CatchContentObject) -> bool:
  472. """
  473. 联通拟在建类型
  474. 业主单位名称为空检测
  475. :param obj:代表一个item
  476. :return:返回true 代表异常
  477. """
  478. owner = obj.get("owner", "")
  479. if not owner:
  480. return True
  481. return False
  482. def check_total_investment(self,obj, catch_content: CatchContentObject) -> bool:
  483. """
  484. 联通拟在建类型
  485. 投资金额(万元)为空检测
  486. :param obj:代表一个item
  487. :return:返回true 代表异常
  488. """
  489. total_investment = obj.get("total_investment", "")
  490. if not total_investment:
  491. return True
  492. return False
  493. def check_area_code(self,obj, catch_content: CatchContentObject) -> bool:
  494. """
  495. 联通拟在建类型
  496. 省份为空检测
  497. :param obj:代表一个item
  498. :return:返回true 代表异常
  499. """
  500. area_code = obj.get("area_code", "")
  501. if not area_code:
  502. return True
  503. return False
  504. def check_city_code(self, obj, catch_content: CatchContentObject) -> bool:
  505. """
  506. 联通拟在建类型
  507. 城市为空检测
  508. :param obj:代表一个item
  509. :return:返回true 代表异常
  510. """
  511. city_code = obj.get("city_code", "")
  512. if not city_code:
  513. return True
  514. return False
  515. def check_capital(self,obj, catch_content: CatchContentObject) -> bool:
  516. """
  517. 联通拟在建类型
  518. 投资金额(万元)为空检测
  519. :param obj:代表一个item
  520. :return:返回true 代表异常
  521. """
  522. capital = obj.get("capital", "")
  523. if not capital:
  524. return True
  525. return False
  526. def check_project_stage(self,obj, catch_content: CatchContentObject) -> bool:
  527. """
  528. 联通拟在建类型
  529. 项目阶段为空检测
  530. :param obj:代表一个item
  531. :return:返回true 代表异常
  532. """
  533. project_stage = obj.get("project_stage_code", "")
  534. if not project_stage:
  535. return True
  536. return False
  537. def check_procure_content(self,obj, catch_content: CatchContentObject) -> bool:
  538. """
  539. 联通预算类型
  540. 项目情况为空检测
  541. :param obj:代表一个item
  542. :return:返回true 代表异常
  543. """
  544. procure_content = obj.get("procure_content", "")
  545. if not procure_content:
  546. return True
  547. return False
  548. def check_kpi(self,obj, catch_content: CatchContentObject) -> bool:
  549. """
  550. 联通预算类型
  551. 项目目标为空检测
  552. :param obj:代表一个item
  553. :return:返回true 代表异常
  554. """
  555. kpi = obj.get("kpi", "")
  556. if not kpi:
  557. return True
  558. return False
  559. def check_institution(self,obj, catch_content: CatchContentObject) -> bool:
  560. """
  561. 联通预算类型
  562. 项目单位为空检测
  563. :param obj:代表一个item
  564. :return:返回true 代表异常
  565. """
  566. institution = obj.get("institution", "")
  567. if not institution:
  568. return True
  569. return False