contract_service.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. /*
  2. * @description: 合同数据相关操作
  3. * @Author: CP
  4. * @Date: 2020-10-27 11:28:24
  5. * @FilePath: \construction_management\services\contract_service.go
  6. */
  7. package services
  8. import (
  9. "errors"
  10. "fmt"
  11. "html"
  12. "log"
  13. "strconv"
  14. "time"
  15. "github.com/kataras/iris/v12"
  16. "go.mod/comm"
  17. "go.mod/conf"
  18. "go.mod/dao"
  19. "go.mod/datasource"
  20. "go.mod/models"
  21. "go.mod/web/viewmodels"
  22. )
  23. //定义项目用户Service接口
  24. type ContractService interface {
  25. ValidRuleDepth(ctx iris.Context) (*viewmodels.TreeSectionContract, error)
  26. ValidRuleTemplate(ctx iris.Context) (*viewmodels.TreeSectionContract, error)
  27. ValidRuleSectionAdd(ctx iris.Context) (*viewmodels.TreeSectionContract, error)
  28. ValidRuleSectionDelete(ctx iris.Context) (*viewmodels.TreeSectionContract, error)
  29. ValidRuleGet(ctx iris.Context) (*viewmodels.TreeSectionContract, error)
  30. ValidRuleSerial(ctx iris.Context) (*viewmodels.TreeSectionContract, error)
  31. ValidRuleContractAdd(ctx iris.Context) (*viewmodels.Contracts, error)
  32. ValidRuleContractEdi(ctx iris.Context) (*viewmodels.Contracts, error)
  33. ValidRuleContractDel(ctx iris.Context) (*viewmodels.Contracts, error)
  34. ValidRuleContractRetrunAdd(ctx iris.Context) (*viewmodels.ContractsReturn, error)
  35. ValidRuleContractRetrun(ctx iris.Context) (*viewmodels.ContractsReturn, error)
  36. ValidRuleContractRetrunDel(ctx iris.Context) (*viewmodels.ContractsReturn, error)
  37. Get(treeId int, bidsectionId int, projectId int) *viewmodels.TreeSectionContract
  38. GetSectionTreeContract(attribution string, bidsectionId int, projectId int, treeType int) []*viewmodels.Contracts
  39. GetSecionTree(bidsectionId int, projectId int, treeType int) *viewmodels.TreeSectionContract
  40. SetSection(templateNumber int, bidsectionId int, projectIdInt int, treeType int) error
  41. SectionAdd(sectionData *viewmodels.TreeSectionContract, bidsectionId int, projectId int, treeType int) error
  42. SectionSave(sectionData *viewmodels.TreeSectionContract, bidsectionId int, projectId int, treeType int) error
  43. UpdateSerial(sectionData *viewmodels.TreeSectionContract, bidsectionId int, projectId int, treeType int) error
  44. SectionDelete(treeId int, bidsectionId int, projectId int, treeType int) error
  45. MoveDepth(sectionData *viewmodels.TreeSectionContract, bidsectionId int, projectId int, treeType int) error
  46. MoveSerial(sectionData *viewmodels.TreeSectionContract, bidsectionId int, projectId int, treeType int) error
  47. GetContract(contractId int) *viewmodels.Contracts
  48. Add(contractData *viewmodels.Contracts, projectId int, bidsectionId int, treeId int) error
  49. Update(contractData *viewmodels.Contracts, projectId int, bidsectionId int, treeId int) error
  50. Delete(projectId int, bidsectionId int, treeId int, id int) error
  51. Close(projectId int, bidsectionId int, treeId int, id int) error
  52. Unlock(projectId int, bidsectionId int, treeId int, id int) error
  53. ReturnCreate(returnData *viewmodels.ContractsReturn, projectId int, bidsectionId int, contractsId int, projectAccountId int) error
  54. ReturnUpdate(returnData *viewmodels.ContractsReturn, projectId int, bidsectionId int, contractsId int, id int) error
  55. ReturnAll(projectId int, bidsectionId int, contractsId int, page int) []*viewmodels.ContractsReturn
  56. ReturnDelete(projectId int, bidsectionId int, contractsId int, id int) error
  57. //支出合同
  58. AddExpenditure(contractData *viewmodels.Contracts, projectId int, bidsectionId int, treeId int) error
  59. UpdateExpenditure(contractData *viewmodels.Contracts, projectId int, bidsectionId int, treeId int) error
  60. DeleteExpenditure(projectId int, bidsectionId int, treeId int, id int) error
  61. }
  62. //返回service操作类
  63. type contractService struct {
  64. treeContractDao *dao.TreeContractDao
  65. contractDao *dao.ContractDao
  66. contractReturnDao *dao.ContractReturnDao
  67. treeDao *dao.TreeDao
  68. annexDao *dao.AnnexDao
  69. }
  70. //创建项目用户service
  71. func NewContractService() ContractService {
  72. return &contractService{
  73. treeContractDao: dao.NewTreeContractDao(datasource.InstanceDbMaster()),
  74. contractDao: dao.NewContractDao(datasource.InstanceDbMaster()),
  75. contractReturnDao: dao.NewContractReturnDao(datasource.InstanceDbMaster()),
  76. treeDao: dao.NewTreeDao(datasource.InstanceDbMaster()),
  77. annexDao: dao.NewAnnexDao(datasource.InstanceDbMaster()),
  78. }
  79. }
  80. // 升级降级规则验证
  81. func (s *contractService) ValidRuleDepth(ctx iris.Context) (*viewmodels.TreeSectionContract, error) {
  82. treeSectionVaild := &viewmodels.TreeSectionContract{}
  83. err := ctx.ReadJSON(treeSectionVaild)
  84. if err != nil {
  85. log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
  86. return treeSectionVaild, err
  87. }
  88. err = treeSectionVaild.ValidateDepth()
  89. if err != nil {
  90. log.Println("参数验证错误, error=", err)
  91. return treeSectionVaild, err
  92. }
  93. return treeSectionVaild, nil
  94. }
  95. // 模板规则验证
  96. func (s *contractService) ValidRuleTemplate(ctx iris.Context) (*viewmodels.TreeSectionContract, error) {
  97. treeSectionVaild := &viewmodels.TreeSectionContract{}
  98. err := ctx.ReadJSON(treeSectionVaild)
  99. if err != nil {
  100. log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
  101. return treeSectionVaild, err
  102. }
  103. err = treeSectionVaild.ValidateTemplate()
  104. if err != nil {
  105. log.Println("参数验证错误, error=", err)
  106. return treeSectionVaild, err
  107. }
  108. return treeSectionVaild, nil
  109. }
  110. // 模板规则新增项目节
  111. func (s *contractService) ValidRuleSectionAdd(ctx iris.Context) (*viewmodels.TreeSectionContract, error) {
  112. treeSectionVaild := &viewmodels.TreeSectionContract{}
  113. err := ctx.ReadJSON(treeSectionVaild)
  114. if err != nil {
  115. log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
  116. return treeSectionVaild, err
  117. }
  118. err = treeSectionVaild.ValidateSectionAdd()
  119. if err != nil {
  120. log.Println("参数验证错误, error=", err)
  121. return treeSectionVaild, err
  122. }
  123. return treeSectionVaild, nil
  124. }
  125. // 模板规则新增项目节
  126. func (s *contractService) ValidRuleSectionDelete(ctx iris.Context) (*viewmodels.TreeSectionContract, error) {
  127. treeSectionVaild := &viewmodels.TreeSectionContract{}
  128. err := ctx.ReadForm(treeSectionVaild)
  129. if err != nil {
  130. log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
  131. return treeSectionVaild, err
  132. }
  133. err = treeSectionVaild.ValidateSectionDelete()
  134. if err != nil {
  135. log.Println("参数验证错误, error=", err)
  136. return treeSectionVaild, err
  137. }
  138. return treeSectionVaild, nil
  139. }
  140. func (s *contractService) ValidRuleGet(ctx iris.Context) (*viewmodels.TreeSectionContract, error) {
  141. treeSectionVaild := &viewmodels.TreeSectionContract{}
  142. err := ctx.ReadForm(treeSectionVaild)
  143. if err != nil {
  144. log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
  145. return treeSectionVaild, err
  146. }
  147. err = treeSectionVaild.ValidateSectionDelete()
  148. if err != nil {
  149. log.Println("参数验证错误, error=", err)
  150. return treeSectionVaild, err
  151. }
  152. return treeSectionVaild, nil
  153. }
  154. // 验证序号相关
  155. func (s *contractService) ValidRuleSerial(ctx iris.Context) (*viewmodels.TreeSectionContract, error) {
  156. treeSectionVaild := &viewmodels.TreeSectionContract{}
  157. err := ctx.ReadJSON(treeSectionVaild)
  158. if err != nil {
  159. log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
  160. return treeSectionVaild, err
  161. }
  162. err = treeSectionVaild.ValidateSectionSerial()
  163. if err != nil {
  164. log.Println("参数验证错误, error=", err)
  165. return treeSectionVaild, err
  166. }
  167. return treeSectionVaild, nil
  168. }
  169. // 新增合同参数验证
  170. func (s *contractService) ValidRuleContractAdd(ctx iris.Context) (*viewmodels.Contracts, error) {
  171. // 创建一个存放前端传过来参数
  172. contractsVaild := &viewmodels.Contracts{}
  173. // 存放raw的值,放入到contractsVaild
  174. err := ctx.ReadJSON(contractsVaild)
  175. if err != nil {
  176. log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
  177. return contractsVaild, err
  178. }
  179. // 验证合同传参
  180. err = contractsVaild.ValidateAdd()
  181. if err != nil {
  182. log.Println("参数验证错误, error=", err)
  183. return contractsVaild, err
  184. }
  185. // xss
  186. contractsVaild.Code = html.EscapeString(contractsVaild.Code)
  187. contractsVaild.Name = html.EscapeString(contractsVaild.Name)
  188. contractsVaild.Price = html.EscapeString(contractsVaild.Price)
  189. return contractsVaild, nil
  190. }
  191. // 校验编辑接口
  192. func (s *contractService) ValidRuleContractEdi(ctx iris.Context) (*viewmodels.Contracts, error) {
  193. // 创建一个存放前端传过来参数
  194. contractsVaild := &viewmodels.Contracts{}
  195. // 存放raw的值,放入到contractsVaild
  196. err := ctx.ReadJSON(contractsVaild)
  197. if err != nil {
  198. log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
  199. return contractsVaild, err
  200. }
  201. // 验证合同传参
  202. err = contractsVaild.ValidateEdi()
  203. if err != nil {
  204. log.Println("参数验证错误, error=", err)
  205. return contractsVaild, err
  206. }
  207. contractsVaild.Content = html.EscapeString(contractsVaild.Content)
  208. contractsVaild.Name = html.EscapeString(contractsVaild.Name)
  209. contractsVaild.Price = html.EscapeString(contractsVaild.Price)
  210. contractsVaild.PartyA = html.EscapeString(contractsVaild.PartyA)
  211. contractsVaild.PartyASigner = html.EscapeString(contractsVaild.PartyASigner)
  212. contractsVaild.PartyB = html.EscapeString(contractsVaild.PartyB)
  213. contractsVaild.PartyBSigner = html.EscapeString(contractsVaild.PartyBSigner)
  214. return contractsVaild, nil
  215. }
  216. // 校验删除合同参数
  217. func (s *contractService) ValidRuleContractDel(ctx iris.Context) (*viewmodels.Contracts, error) {
  218. // 创建一个存放前端传过来参数
  219. contractsVaild := &viewmodels.Contracts{}
  220. // 存放raw的值,放入到contractsVaild
  221. err := ctx.ReadForm(contractsVaild)
  222. if err != nil {
  223. log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
  224. return contractsVaild, err
  225. }
  226. // 验证合同传参
  227. err = contractsVaild.ValidateDel()
  228. if err != nil {
  229. log.Println("参数验证错误, error=", err)
  230. return contractsVaild, err
  231. }
  232. return contractsVaild, nil
  233. }
  234. //------------------------------------------------------------
  235. // 获得项目节
  236. func (s *contractService) Get(treeId int, bidsectionId int, projectId int) *viewmodels.TreeSectionContract {
  237. // 1.获得项目节
  238. section := s.treeContractDao.Get(treeId, bidsectionId, projectId, 0)
  239. // 2.构造数据
  240. sectionVM := s.makeSectionView(section)
  241. // 3.更新 上移和下一的限制
  242. youngerBrotherList := s.treeContractDao.GetYoungerBrother(section.Serial, section.Depth, section.ParentId, bidsectionId, projectId, 0)
  243. if len(youngerBrotherList) == 0 {
  244. sectionVM.IsEnd = true
  245. }
  246. sectionVM.ElderBrother = true
  247. elderBrotherList := s.treeContractDao.GetElderBrother(section.Serial, section.Depth, section.ParentId, bidsectionId, projectId, 0)
  248. if len(elderBrotherList) == 0 {
  249. sectionVM.ElderBrother = false
  250. }
  251. return sectionVM
  252. }
  253. // 获得合同详情
  254. func (s *contractService) GetContract(contractId int) *viewmodels.Contracts {
  255. contract := s.contractDao.Get(contractId)
  256. contractsVM := &viewmodels.Contracts{}
  257. id, _ := comm.AesEncrypt(strconv.Itoa(contract.Id), conf.SignSecret)
  258. treeId, _ := comm.AesEncrypt(strconv.Itoa(contract.TreeId), conf.SignSecret)
  259. bidsectionId, _ := comm.AesEncrypt(strconv.Itoa(contract.BidsectionId), conf.SignSecret)
  260. contractsVM.Id = id
  261. contractsVM.TreeId = treeId
  262. contractsVM.ContractsType = contract.ContractsType
  263. contractsVM.BidsectionId = bidsectionId
  264. contractsVM.Name = contract.Name
  265. contractsVM.Content = contract.Content
  266. contractsVM.Code = contract.Code
  267. contractsVM.PartyA = contract.PartyA
  268. contractsVM.PartyASigner = contract.PartyASigner
  269. contractsVM.PartyB = contract.PartyB
  270. contractsVM.PartyBSigner = contract.PartyBSigner
  271. contractsVM.Remarks = contract.Remarks
  272. contractsVM.Price = contract.Price
  273. contractsVM.Returned = contract.Returned
  274. contractsVM.Paid = contract.Paid
  275. contractsVM.Status = contract.Status
  276. contractsVM.Locking = contract.Locking
  277. contractsVM.CreateTime = contract.CreateTime.Format(conf.SysTimeform)
  278. contractsVM.UpdateTime = contract.UpdateTime.Format(conf.SysTimeform)
  279. contractsVM.SignerTime = contract.SignerTime.Format(conf.SysTimeform)
  280. return contractsVM
  281. }
  282. // 新增合同
  283. func (s *contractService) Add(contractData *viewmodels.Contracts, projectId int, bidsectionId int, treeId int) error {
  284. // 1. 项目节存在
  285. contracts := s.treeContractDao.Get(treeId, bidsectionId, projectId, 0)
  286. if contracts.Id == 0 {
  287. return errors.New("未找到项目节")
  288. }
  289. // k := int32(projectId)
  290. // 2.项目节是没有合同
  291. if contracts.ContractId != 0 {
  292. return errors.New("该项目节上已经存在合同")
  293. }
  294. // 3.新增合同 --合计标段上的金额
  295. contractsCm := &models.CmContracts{}
  296. contractsCm.Code = contractData.Code
  297. contractsCm.Name = contractData.Name
  298. contractsCm.ContractsType = 1
  299. contractsCm.Price = contractData.Price
  300. contractsCm.Returned = "0"
  301. contractsCm.Paid = "0"
  302. contractsCm.TreeId = treeId
  303. contractsCm.ProjectId = projectId
  304. contractsCm.BidsectionId = bidsectionId
  305. contractsCm.Status = 0
  306. contractsCm.CreateTime = time.Now()
  307. contractsCm.UpdateTime = time.Now()
  308. err := s.contractDao.Add(contractsCm)
  309. if err != nil {
  310. return err
  311. }
  312. // 3.获得该标段下合同总数 - 总收入金额
  313. contractTotal, priceTotal := s.getContractTotalAndPrice(bidsectionId, projectId, 0)
  314. // 更新标段目录上合同金额和总数
  315. err = s.treeDao.UpdateContractsAndIncomePrice(projectId, bidsectionId, contractTotal, priceTotal)
  316. if err != nil {
  317. return err
  318. }
  319. return nil
  320. }
  321. // 更新合同
  322. func (s *contractService) Update(contractData *viewmodels.Contracts, projectId int, bidsectionId int, treeId int) error {
  323. // 1. 项目节存在
  324. contractsTree := s.treeContractDao.Get(treeId, bidsectionId, projectId, 0)
  325. if contractsTree.Id == 0 {
  326. return errors.New("未找到项目节")
  327. }
  328. // 2.项目节是没有合同
  329. if contractsTree.ContractId == 0 {
  330. return errors.New("该项目节上没有找到合同")
  331. }
  332. // 3.合同锁定 不能删除
  333. if contractsTree.ContractLocking == 1 {
  334. return errors.New("该合同已锁定")
  335. }
  336. contractsCm := &models.CmContracts{}
  337. contractsCm.Id = contractsTree.ContractId
  338. contractsCm.Content = contractData.Content
  339. contractsCm.Name = contractData.Name
  340. contractsCm.Price = contractData.Price
  341. contractsCm.PartyA = contractData.PartyA
  342. contractsCm.PartyASigner = contractData.PartyASigner
  343. contractsCm.PartyB = contractData.PartyB
  344. contractsCm.PartyBSigner = contractData.PartyBSigner
  345. loc, _ := time.LoadLocation("Local")
  346. SignerTime, err := time.ParseInLocation(conf.SysTimeform, contractData.SignerTime, loc)
  347. if err != nil {
  348. return errors.New("签约时间填写异常")
  349. }
  350. contractsCm.SignerTime = SignerTime
  351. contractsCm.Remarks = contractData.Remarks
  352. columns := []string{"Content", "Name", "Price", "PartyA", "PartyASigner", "PartyB", "PartyBSigner"}
  353. err = s.contractDao.Update(contractsCm, columns, projectId, bidsectionId, treeId)
  354. if err != nil {
  355. return err
  356. }
  357. // 3.获得该标段下合同总数 - 总收入金额
  358. contractTotal, priceTotal := s.getContractTotalAndPrice(bidsectionId, projectId, 0)
  359. // 更新标段目录上合同金额和总数
  360. err = s.treeDao.UpdateContractsAndIncomePrice(projectId, bidsectionId, contractTotal, priceTotal)
  361. if err != nil {
  362. return err
  363. }
  364. return nil
  365. }
  366. // 删除合同
  367. func (s *contractService) Delete(projectId int, bidsectionId int, treeId int, id int) error {
  368. // 1. 项目节存在
  369. contractsTree := s.treeContractDao.Get(treeId, bidsectionId, projectId, 0)
  370. if contractsTree.Id == 0 {
  371. return errors.New("未找到项目节")
  372. }
  373. // 2.项目节是没有合同
  374. if contractsTree.ContractId == 0 {
  375. return errors.New("该项目节上没有找到合同")
  376. }
  377. // 3.合同锁定 不能删除
  378. if contractsTree.ContractLocking == 1 {
  379. return errors.New("该合同已锁定")
  380. }
  381. // 删除合同
  382. err := s.contractDao.Delete(projectId, bidsectionId, treeId, id)
  383. if err != nil {
  384. return err
  385. }
  386. // 3.获得该标段下合同总数 - 总收入金额
  387. contractTotal, priceTotal := s.getContractTotalAndPrice(bidsectionId, projectId, 0)
  388. // 更新标段目录上合同金额和总数
  389. err = s.treeDao.UpdateContractsAndIncomePrice(projectId, bidsectionId, contractTotal, priceTotal)
  390. if err != nil {
  391. return err
  392. }
  393. // 4.更新回款总金额
  394. err = s.contractReturnDao.UpdateTotalPrice(projectId, bidsectionId, id)
  395. if err != nil {
  396. return err
  397. }
  398. return nil
  399. }
  400. // 关闭合同
  401. func (s *contractService) Close(projectId int, bidsectionId int, treeId int, id int) error {
  402. // 1. 项目节存在
  403. contractsTree := s.treeContractDao.Get(treeId, bidsectionId, projectId, 0)
  404. if contractsTree.Id == 0 {
  405. return errors.New("未找到项目节")
  406. }
  407. // 2.项目节是没有合同
  408. if contractsTree.ContractId == 0 {
  409. return errors.New("该项目节上没有找到合同")
  410. }
  411. // 3.合同锁定 不能删除
  412. if contractsTree.ContractLocking == 1 {
  413. return errors.New("该合同已锁定")
  414. }
  415. // 关闭合同
  416. err := s.contractDao.Close(projectId, bidsectionId, treeId, id)
  417. if err != nil {
  418. return err
  419. }
  420. return nil
  421. }
  422. // 解锁合同
  423. func (s *contractService) Unlock(projectId int, bidsectionId int, treeId int, id int) error {
  424. // 1. 项目节存在
  425. contractsTree := s.treeContractDao.Get(treeId, bidsectionId, projectId, 0)
  426. if contractsTree.Id == 0 {
  427. return errors.New("未找到项目节")
  428. }
  429. // 2.项目节是没有合同
  430. if contractsTree.ContractId == 0 {
  431. return errors.New("该项目节上没有找到合同")
  432. }
  433. // 解锁合同
  434. err := s.contractDao.Unlock(projectId, bidsectionId, treeId, id)
  435. if err != nil {
  436. return err
  437. }
  438. return nil
  439. }
  440. // 获得合同总数量和总金额
  441. func (s *contractService) getContractTotalAndPrice(bidsectionId int, projectId int, treeType int) (contractTotal int, priceTotal float64) {
  442. contractListAll := s.treeContractDao.GetContractAll(bidsectionId, projectId)
  443. // 获得收入合同
  444. contractList := s.treeContractDao.GetContract(bidsectionId, projectId, treeType)
  445. priceTotal = 0.00
  446. for _, item := range contractList {
  447. contractPrice, _ := strconv.ParseFloat(item.ContractPrice, 64)
  448. priceTotal = priceTotal + contractPrice
  449. }
  450. // 合同总数
  451. // contractTotal = len(contractList) + 1
  452. contractTotal = len(contractListAll)
  453. // 合同收入总金额
  454. // price, _ := strconv.ParseFloat(priceString, 64)
  455. // priceTotal = priceTotal + price
  456. // 保留2位小数
  457. priceTotal, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", priceTotal), 64)
  458. return contractTotal, priceTotal
  459. }