contract_service.go 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736
  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. "github.com/shopspring/decimal"
  17. "go.mod/comm"
  18. "go.mod/conf"
  19. "go.mod/dao"
  20. "go.mod/datasource"
  21. "go.mod/models"
  22. "go.mod/web/viewmodels"
  23. )
  24. // 定义项目用户Service接口
  25. type ContractService interface {
  26. ValidRuleDepth(ctx iris.Context) (*viewmodels.TreeSectionContract, error)
  27. ValidRuleTemplate(ctx iris.Context) (*viewmodels.TreeSectionContract, error)
  28. ValidRuleSectionAdd(ctx iris.Context) (*viewmodels.TreeSectionContract, error)
  29. ValidRuleSectionDelete(ctx iris.Context) (*viewmodels.TreeSectionContract, error)
  30. ValidRuleSectionNot(ctx iris.Context) (*viewmodels.TreeSectionContract, error)
  31. ValidRuleGet(ctx iris.Context) (*viewmodels.TreeSectionContract, error)
  32. ValidRuleSerial(ctx iris.Context) (*viewmodels.TreeSectionContract, error)
  33. ValidRuleContractAdd(ctx iris.Context) (*viewmodels.Contracts, error)
  34. ValidRuleContractEdi(ctx iris.Context) (*viewmodels.Contracts, error)
  35. ValidRuleContractDel(ctx iris.Context) (*viewmodels.Contracts, error)
  36. ValidRuleContractClose(ctx iris.Context) (*viewmodels.Contracts, error)
  37. ValidRuleContractRetrunAdd(ctx iris.Context) (*viewmodels.ContractsReturn, error)
  38. ValidRuleContractRetrun(ctx iris.Context) (*viewmodels.ContractsReturn, error)
  39. ValidRuleContractRetrunDel(ctx iris.Context) (*viewmodels.ContractsReturn, error)
  40. ValidRuleContractPaidAdd(ctx iris.Context) (*viewmodels.ContractsPaid, error)
  41. ValidRuleContractPaid(ctx iris.Context) (*viewmodels.ContractsPaid, error)
  42. ValidRuleContractPaidDel(ctx iris.Context) (*viewmodels.ContractsPaid, error)
  43. // 项目节
  44. Get(treeId int, bidsectionId int, projectId int, treeType int) *viewmodels.TreeSectionContract
  45. GetSectionTreeContract(attribution string, bidsectionId int, projectId int, treeType int) []*viewmodels.Contracts
  46. GetSecionTree(bidsectionId int, projectId int, treeType int) *viewmodels.TreeSectionContract
  47. SetSection(templateNumber int, bidsectionId int, projectIdInt int, treeType int) error
  48. SectionAdd(sectionData *viewmodels.TreeSectionContract, bidsectionId int, projectId int, treeType int) (*models.CmTreeContracts, error)
  49. ContractSectionAdd(sectionData *viewmodels.TreeSectionContract, bidsectionId int, projectId int, treeType int) (*models.CmTreeContracts, error)
  50. SectionSave(sectionData *viewmodels.TreeSectionContract, bidsectionId int, projectId int, treeType int) error
  51. UpdateSerial(sectionData *viewmodels.TreeSectionContract, bidsectionId int, projectId int, treeType int) error
  52. SectionDelete(treeId int, bidsectionId int, projectId int, treeType int) error
  53. MoveDepth(sectionData *viewmodels.TreeSectionContract, bidsectionId int, projectId int, treeType int) error
  54. MoveSerial(sectionData *viewmodels.TreeSectionContract, bidsectionId int, projectId int, treeType int) error
  55. GetSecionTreeNotContract(bidsectionId int, projectId int, treeType int) *viewmodels.TreeSectionContract
  56. GetContract(contractId int) *viewmodels.Contracts
  57. Add(contractData *viewmodels.Contracts, projectId int, bidsectionId int, treeId int) error
  58. Update(contractData *viewmodels.Contracts, projectId int, bidsectionId int, treeId int) error
  59. Delete(projectId int, bidsectionId int, treeId int, id int) error
  60. Close(projectId int, bidsectionId int, treeId int, id int, treeType int, settlementCode string) error
  61. Unlock(projectId int, bidsectionId int, treeId int, id int, treeType int) error
  62. GetSurvey(bidsectionId int, projectId int, contractsType int) map[string]interface{}
  63. ReturnCreate(returnData *viewmodels.ContractsReturn, projectId int, bidsectionId int, contractsId int, projectAccountId int) error
  64. ReturnUpdate(returnData *viewmodels.ContractsReturn, projectId int, bidsectionId int, contractsId int, id int) error
  65. ReturnAll(projectId int, bidsectionId int, contractsId int, page int) []*viewmodels.ContractsReturn
  66. ReturnDelete(projectId int, bidsectionId int, contractsId int, id int) error
  67. //支出合同
  68. AddExpenditure(contractData *viewmodels.Contracts, projectId int, bidsectionId int, treeId int) error
  69. UpdateExpenditure(contractData *viewmodels.Contracts, projectId int, bidsectionId int, treeId int) error
  70. DeleteExpenditure(projectId int, bidsectionId int, treeId int, id int) error
  71. // 已支付
  72. PaidAll(projectId int, bidsectionId int, contractsId int, page int) []*viewmodels.ContractsPaid
  73. PaidCreate(returnData *viewmodels.ContractsPaid, projectId int, bidsectionId int, contractsId int, projectAccountId int) error
  74. PaidUpdate(returnData *viewmodels.ContractsPaid, projectId int, bidsectionId int, contractsId int, id int) error
  75. PaidDelete(projectId int, bidsectionId int, contractsId int, id int) error
  76. }
  77. // 返回service操作类
  78. type contractService struct {
  79. treeContractDao *dao.TreeContractDao
  80. contractDao *dao.ContractDao
  81. contractReturnDao *dao.ContractReturnDao
  82. contractPaidDao *dao.ContractPaidDao
  83. treeDao *dao.TreeDao
  84. annexDao *dao.AnnexDao
  85. }
  86. // 创建项目用户service
  87. func NewContractService() ContractService {
  88. return &contractService{
  89. treeContractDao: dao.NewTreeContractDao(datasource.InstanceDbMaster()),
  90. contractDao: dao.NewContractDao(datasource.InstanceDbMaster()),
  91. contractReturnDao: dao.NewContractReturnDao(datasource.InstanceDbMaster()),
  92. contractPaidDao: dao.NewContractPaidDao(datasource.InstanceDbMaster()),
  93. treeDao: dao.NewTreeDao(datasource.InstanceDbMaster()),
  94. annexDao: dao.NewAnnexDao(datasource.InstanceDbMaster()),
  95. }
  96. }
  97. // 升级降级规则验证
  98. func (s *contractService) ValidRuleDepth(ctx iris.Context) (*viewmodels.TreeSectionContract, error) {
  99. treeSectionVaild := &viewmodels.TreeSectionContract{}
  100. err := ctx.ReadJSON(treeSectionVaild)
  101. if err != nil {
  102. log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
  103. return treeSectionVaild, err
  104. }
  105. err = treeSectionVaild.ValidateDepth()
  106. if err != nil {
  107. log.Println("参数验证错误, error=", err)
  108. return treeSectionVaild, err
  109. }
  110. return treeSectionVaild, nil
  111. }
  112. // 模板规则验证
  113. func (s *contractService) ValidRuleTemplate(ctx iris.Context) (*viewmodels.TreeSectionContract, error) {
  114. treeSectionVaild := &viewmodels.TreeSectionContract{}
  115. err := ctx.ReadJSON(treeSectionVaild)
  116. if err != nil {
  117. log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
  118. return treeSectionVaild, err
  119. }
  120. err = treeSectionVaild.ValidateTemplate()
  121. if err != nil {
  122. log.Println("参数验证错误, error=", err)
  123. return treeSectionVaild, err
  124. }
  125. return treeSectionVaild, nil
  126. }
  127. // 模板规则新增项目节
  128. func (s *contractService) ValidRuleSectionAdd(ctx iris.Context) (*viewmodels.TreeSectionContract, error) {
  129. treeSectionVaild := &viewmodels.TreeSectionContract{}
  130. err := ctx.ReadJSON(treeSectionVaild)
  131. if err != nil {
  132. log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
  133. return treeSectionVaild, err
  134. }
  135. err = treeSectionVaild.ValidateSectionAdd()
  136. if err != nil {
  137. log.Println("参数验证错误, error=", err)
  138. return treeSectionVaild, err
  139. }
  140. return treeSectionVaild, nil
  141. }
  142. // 模板规则新增项目节
  143. func (s *contractService) ValidRuleSectionDelete(ctx iris.Context) (*viewmodels.TreeSectionContract, error) {
  144. treeSectionVaild := &viewmodels.TreeSectionContract{}
  145. err := ctx.ReadForm(treeSectionVaild)
  146. if err != nil {
  147. log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
  148. return treeSectionVaild, err
  149. }
  150. err = treeSectionVaild.ValidateSectionDelete()
  151. if err != nil {
  152. log.Println("参数验证错误, error=", err)
  153. return treeSectionVaild, err
  154. }
  155. return treeSectionVaild, nil
  156. }
  157. func (s *contractService) ValidRuleSectionNot(ctx iris.Context) (*viewmodels.TreeSectionContract, error) {
  158. treeSectionVaild := &viewmodels.TreeSectionContract{}
  159. err := ctx.ReadForm(treeSectionVaild)
  160. if err != nil {
  161. log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
  162. return treeSectionVaild, err
  163. }
  164. err = treeSectionVaild.ValidateSectionNot()
  165. if err != nil {
  166. log.Println("参数验证错误, error=", err)
  167. return treeSectionVaild, err
  168. }
  169. return treeSectionVaild, nil
  170. }
  171. func (s *contractService) ValidRuleGet(ctx iris.Context) (*viewmodels.TreeSectionContract, error) {
  172. treeSectionVaild := &viewmodels.TreeSectionContract{}
  173. err := ctx.ReadForm(treeSectionVaild)
  174. if err != nil {
  175. log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
  176. return treeSectionVaild, err
  177. }
  178. err = treeSectionVaild.ValidateSectionDelete()
  179. if err != nil {
  180. log.Println("参数验证错误, error=", err)
  181. return treeSectionVaild, err
  182. }
  183. return treeSectionVaild, nil
  184. }
  185. // 验证序号相关
  186. func (s *contractService) ValidRuleSerial(ctx iris.Context) (*viewmodels.TreeSectionContract, error) {
  187. treeSectionVaild := &viewmodels.TreeSectionContract{}
  188. err := ctx.ReadJSON(treeSectionVaild)
  189. if err != nil {
  190. log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
  191. return treeSectionVaild, err
  192. }
  193. err = treeSectionVaild.ValidateSectionSerial()
  194. if err != nil {
  195. log.Println("参数验证错误, error=", err)
  196. return treeSectionVaild, err
  197. }
  198. return treeSectionVaild, nil
  199. }
  200. // 新增合同参数验证
  201. func (s *contractService) ValidRuleContractAdd(ctx iris.Context) (*viewmodels.Contracts, error) {
  202. // 创建一个存放前端传过来参数
  203. contractsVaild := &viewmodels.Contracts{}
  204. // 存放raw的值,放入到contractsVaild
  205. err := ctx.ReadJSON(contractsVaild)
  206. if err != nil {
  207. log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
  208. return contractsVaild, err
  209. }
  210. // 验证合同传参
  211. err = contractsVaild.ValidateAdd()
  212. if err != nil {
  213. log.Println("参数验证错误, error=", err)
  214. return contractsVaild, err
  215. }
  216. // xss
  217. contractsVaild.Code = html.EscapeString(contractsVaild.Code)
  218. contractsVaild.Name = html.EscapeString(contractsVaild.Name)
  219. // contractsVaild.Price = html.EscapeString(contractsVaild.Price)
  220. return contractsVaild, nil
  221. }
  222. // 校验编辑接口
  223. func (s *contractService) ValidRuleContractEdi(ctx iris.Context) (*viewmodels.Contracts, error) {
  224. // 创建一个存放前端传过来参数
  225. contractsVaild := &viewmodels.Contracts{}
  226. // 存放raw的值,放入到contractsVaild
  227. err := ctx.ReadJSON(contractsVaild)
  228. if err != nil {
  229. log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
  230. return contractsVaild, err
  231. }
  232. // 验证合同传参
  233. err = contractsVaild.ValidateEdi()
  234. if err != nil {
  235. log.Println("参数验证错误, error=", err)
  236. return contractsVaild, err
  237. }
  238. contractsVaild.Content = html.EscapeString(contractsVaild.Content)
  239. contractsVaild.Name = html.EscapeString(contractsVaild.Name)
  240. // contractsVaild.Price = html.EscapeString(contractsVaild.Price)
  241. contractsVaild.PartyA = html.EscapeString(contractsVaild.PartyA)
  242. contractsVaild.PartyASigner = html.EscapeString(contractsVaild.PartyASigner)
  243. contractsVaild.PartyB = html.EscapeString(contractsVaild.PartyB)
  244. contractsVaild.PartyBSigner = html.EscapeString(contractsVaild.PartyBSigner)
  245. return contractsVaild, nil
  246. }
  247. // 校验删除合同参数
  248. func (s *contractService) ValidRuleContractDel(ctx iris.Context) (*viewmodels.Contracts, error) {
  249. // 创建一个存放前端传过来参数
  250. contractsVaild := &viewmodels.Contracts{}
  251. // 存放raw的值,放入到contractsVaild
  252. err := ctx.ReadForm(contractsVaild)
  253. if err != nil {
  254. log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
  255. return contractsVaild, err
  256. }
  257. // 验证合同传参
  258. err = contractsVaild.ValidateDel()
  259. if err != nil {
  260. log.Println("参数验证错误, error=", err)
  261. return contractsVaild, err
  262. }
  263. return contractsVaild, nil
  264. }
  265. // 校验关闭合同参数
  266. func (s *contractService) ValidRuleContractClose(ctx iris.Context) (*viewmodels.Contracts, error) {
  267. // 创建一个存放前端传过来参数
  268. contractsVaild := &viewmodels.Contracts{}
  269. // 存放raw的值,放入到contractsVaild
  270. err := ctx.ReadJSON(contractsVaild)
  271. if err != nil {
  272. log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
  273. return contractsVaild, err
  274. }
  275. // 验证合同传参
  276. err = contractsVaild.ValidateDel()
  277. if err != nil {
  278. log.Println("参数验证错误, error=", err)
  279. return contractsVaild, err
  280. }
  281. return contractsVaild, nil
  282. }
  283. // ------------------------------------------------------------
  284. // 获得项目节
  285. func (s *contractService) Get(treeId int, bidsectionId int, projectId int, treeType int) *viewmodels.TreeSectionContract {
  286. // 1.获得项目节
  287. section := s.treeContractDao.Get(treeId, bidsectionId, projectId, treeType)
  288. // 2.构造数据
  289. sectionVM := s.makeSectionView(section)
  290. // 3.更新 上移和下一的限制
  291. youngerBrotherList := s.treeContractDao.GetYoungerBrother(section.Serial, section.Depth, section.ParentId, bidsectionId, projectId, treeType)
  292. if len(youngerBrotherList) == 0 {
  293. sectionVM.IsEnd = true
  294. }
  295. sectionVM.ElderBrother = true
  296. elderBrotherList := s.treeContractDao.GetElderBrother(section.Serial, section.Depth, section.ParentId, bidsectionId, projectId, treeType)
  297. if len(elderBrotherList) == 0 {
  298. sectionVM.ElderBrother = false
  299. }
  300. return sectionVM
  301. }
  302. // 获得合同详情
  303. func (s *contractService) GetContract(contractId int) *viewmodels.Contracts {
  304. contract := s.contractDao.Get(contractId)
  305. contractsVM := s.makeContractVM(contract)
  306. return &contractsVM
  307. }
  308. // 新增合同
  309. func (s *contractService) Add(contractData *viewmodels.Contracts, projectId int, bidsectionId int, treeId int) error {
  310. // 1. 项目节存在
  311. contracts := s.treeContractDao.Get(treeId, bidsectionId, projectId, 0)
  312. if contracts.Id == 0 {
  313. return errors.New("未找到项目节")
  314. }
  315. // 2.项目节是没有合同
  316. if contracts.ContractId != 0 {
  317. return errors.New("该项目节上已经存在合同")
  318. }
  319. // 2-1.查找合同编号是否存在
  320. codeData := s.contractDao.GetByCode(projectId, bidsectionId, contractData.Code, 1)
  321. if len(codeData) != 0 {
  322. return errors.New("该合同编号已经存在")
  323. }
  324. // 3.新增合同 --合计标段上的金额
  325. contractsCm := &models.CmContracts{}
  326. contractsCm.Code = contractData.Code
  327. contractsCm.Name = contractData.Name
  328. contractsCm.ContractsType = 1
  329. contractsCm.Price = fmt.Sprintf("%.2f", contractData.Price)
  330. // contractsCm.Price = contractData.Price
  331. contractsCm.Returned = "0"
  332. contractsCm.Paid = "0"
  333. contractsCm.ContractDeductionTotal = "0"
  334. contractsCm.TreeId = treeId
  335. contractsCm.ProjectId = projectId
  336. contractsCm.BidsectionId = bidsectionId
  337. contractsCm.Status = 0
  338. contractsCm.CreateTime = time.Now()
  339. contractsCm.UpdateTime = time.Now()
  340. err := s.contractDao.Add(contractsCm)
  341. if err != nil {
  342. return err
  343. }
  344. // 3.获得该标段下合同总数 - 总收入金额
  345. contractTotal, priceTotal := s.getContractTotalAndPrice(bidsectionId, projectId, 0)
  346. // 更新标段目录上合同金额和总数
  347. err = s.treeDao.UpdateContractsAndIncomePrice(projectId, bidsectionId, contractTotal, priceTotal)
  348. if err != nil {
  349. return err
  350. }
  351. return nil
  352. }
  353. // 更新合同
  354. func (s *contractService) Update(contractData *viewmodels.Contracts, projectId int, bidsectionId int, treeId int) error {
  355. // 1. 项目节存在
  356. contractsTree := s.treeContractDao.Get(treeId, bidsectionId, projectId, 0)
  357. if contractsTree.Id == 0 {
  358. return errors.New("未找到项目节")
  359. }
  360. // 2.项目节是没有合同
  361. if contractsTree.ContractId == 0 {
  362. return errors.New("该项目节上没有找到合同")
  363. }
  364. // 3.合同锁定 不能删除
  365. if contractsTree.ContractLocking == 1 {
  366. return errors.New("该合同已锁定")
  367. }
  368. // 4.合同金额不能小于回款金额
  369. returnedPrice, _ := decimal.NewFromString(contractsTree.ContractReturned)
  370. price := decimal.NewFromFloat(contractData.Price)
  371. // price, err := decimal.NewFromString(contractData.Price)
  372. // if err != nil {
  373. // return errors.New("金额填写有误")
  374. // }
  375. if returnedPrice.GreaterThan(price) {
  376. return errors.New(fmt.Sprintf("合同金额不能低于%s", contractsTree.ContractReturned))
  377. }
  378. contractsCm := &models.CmContracts{}
  379. contractsCm.Id = contractsTree.ContractId
  380. contractsCm.Content = contractData.Content
  381. contractsCm.Name = contractData.Name
  382. contractsCm.Price = fmt.Sprintf("%.2f", contractData.Price)
  383. // strconv.FormatFloat(contractData.Price, 'f', 1, 64)
  384. // contractsCm.Price = contractData.Price
  385. contractsCm.PartyA = contractData.PartyA
  386. contractsCm.PartyASigner = contractData.PartyASigner
  387. contractsCm.PartyB = contractData.PartyB
  388. contractsCm.PartyBSigner = contractData.PartyBSigner
  389. loc, _ := time.LoadLocation("Local")
  390. SignerTime, err := time.ParseInLocation(conf.SysTimeform, contractData.SignerTime, loc)
  391. if err != nil {
  392. return errors.New("签约时间填写异常")
  393. }
  394. contractsCm.SignerTime = SignerTime
  395. contractsCm.Remarks = contractData.Remarks
  396. columns := []string{"Content", "Name", "Price", "PartyA", "PartyASigner", "PartyB", "PartyBSigner"}
  397. err = s.contractDao.Update(contractsCm, columns, projectId, bidsectionId, treeId)
  398. if err != nil {
  399. return err
  400. }
  401. // 3.获得该标段下合同总数 - 总收入金额
  402. contractTotal, priceTotal := s.getContractTotalAndPrice(bidsectionId, projectId, 0)
  403. // 更新标段目录上合同金额和总数
  404. err = s.treeDao.UpdateContractsAndIncomePrice(projectId, bidsectionId, contractTotal, priceTotal)
  405. if err != nil {
  406. return err
  407. }
  408. return nil
  409. }
  410. // 删除合同
  411. func (s *contractService) Delete(projectId int, bidsectionId int, treeId int, id int) error {
  412. // 1. 项目节存在
  413. contractsTree := s.treeContractDao.Get(treeId, bidsectionId, projectId, 0)
  414. if contractsTree.Id == 0 {
  415. return errors.New("未找到项目节")
  416. }
  417. // 2.项目节是没有合同
  418. if contractsTree.ContractId == 0 {
  419. return errors.New("该项目节上没有找到合同")
  420. }
  421. // 3.合同锁定 不能删除
  422. if contractsTree.ContractLocking == 1 {
  423. return errors.New("该合同已锁定")
  424. }
  425. // 删除合同
  426. err := s.contractDao.Delete(projectId, bidsectionId, treeId, id)
  427. if err != nil {
  428. return err
  429. }
  430. // 3.获得该标段下合同总数 - 总收入金额
  431. contractTotal, priceTotal := s.getContractTotalAndPrice(bidsectionId, projectId, 0)
  432. // 更新标段目录上合同金额和总数
  433. err = s.treeDao.UpdateContractsAndIncomePrice(projectId, bidsectionId, contractTotal, priceTotal)
  434. if err != nil {
  435. return err
  436. }
  437. // 4.更新回款总金额
  438. err = s.contractReturnDao.UpdateTotalPrice(projectId, bidsectionId, id)
  439. if err != nil {
  440. return err
  441. }
  442. return nil
  443. }
  444. // 关闭合同
  445. func (s *contractService) Close(projectId int, bidsectionId int, treeId int, id int, treeType int, settlementCode string) error {
  446. // 1. 项目节存在
  447. contractsTree := s.treeContractDao.Get(treeId, bidsectionId, projectId, treeType)
  448. if contractsTree.Id == 0 {
  449. return errors.New("未找到项目节")
  450. }
  451. // 2.项目节是没有合同
  452. if contractsTree.ContractId == 0 {
  453. return errors.New("该项目节上没有找到合同")
  454. }
  455. // 3.合同锁定 不能删除
  456. if contractsTree.ContractLocking == 1 {
  457. return errors.New("该合同已锁定")
  458. }
  459. // 关闭合同
  460. err := s.contractDao.Close(projectId, bidsectionId, treeId, id, settlementCode)
  461. if err != nil {
  462. return err
  463. }
  464. return nil
  465. }
  466. // 解锁合同
  467. func (s *contractService) Unlock(projectId int, bidsectionId int, treeId int, id int, treeType int) error {
  468. // 1. 项目节存在
  469. contractsTree := s.treeContractDao.Get(treeId, bidsectionId, projectId, treeType)
  470. if contractsTree.Id == 0 {
  471. return errors.New("未找到项目节")
  472. }
  473. // 2.项目节是没有合同
  474. if contractsTree.ContractId == 0 {
  475. return errors.New("该项目节上没有找到合同")
  476. }
  477. // 解锁合同
  478. err := s.contractDao.Unlock(projectId, bidsectionId, treeId, id)
  479. if err != nil {
  480. return err
  481. }
  482. return nil
  483. }
  484. // 获得合同收入概况
  485. func (s *contractService) GetSurvey(bidsectionId int, projectId int, contractsType int) map[string]interface{} {
  486. // 1.获得收入合同
  487. year := time.Now().Year()
  488. incomeList := s.contractDao.GetTypeYear(bidsectionId, projectId, contractsType, year)
  489. // 2.初始化
  490. totalContractPrice := 0.00
  491. totalTypePrice := 0.00
  492. performNumber := 0
  493. closeNumber := 0
  494. uncloseNumber := 0
  495. // 3.当年数据初始化
  496. returnDate := map[string]float64{
  497. fmt.Sprintf("%d-01", year): 0.00,
  498. fmt.Sprintf("%d-02", year): 0.00,
  499. fmt.Sprintf("%d-03", year): 0.00,
  500. fmt.Sprintf("%d-04", year): 0.00,
  501. fmt.Sprintf("%d-05", year): 0.00,
  502. fmt.Sprintf("%d-06", year): 0.00,
  503. fmt.Sprintf("%d-07", year): 0.00,
  504. fmt.Sprintf("%d-08", year): 0.00,
  505. fmt.Sprintf("%d-09", year): 0.00,
  506. fmt.Sprintf("%d-10", year): 0.00,
  507. fmt.Sprintf("%d-11", year): 0.00,
  508. fmt.Sprintf("%d-12", year): 0.00,
  509. }
  510. contractIds := []int{}
  511. for _, item := range incomeList {
  512. contractPrice, _ := strconv.ParseFloat(item.Price, 64)
  513. totalContractPrice = totalContractPrice + contractPrice
  514. // 回款金额或已支付金额合计
  515. contractIds = append(contractIds, item.Id)
  516. // typePrice := 0.00
  517. // if contractsType == 1 {
  518. // typePrice, _ = strconv.ParseFloat(item.Returned, 64)
  519. // totalTypePrice = totalTypePrice + typePrice
  520. // } else {
  521. // typePrice, _ = strconv.ParseFloat(item.Paid, 64)
  522. // totalTypePrice = totalTypePrice + typePrice
  523. // }
  524. if item.Status == 0 {
  525. performNumber = performNumber + 1
  526. } else if item.Status == 1 {
  527. uncloseNumber = uncloseNumber + 1
  528. } else if item.Status == 2 {
  529. closeNumber = closeNumber + 1
  530. }
  531. // returnDate[item.CreateTime.Format(conf.SysTimeformMonth)] = returnDate[item.CreateTime.Format(conf.SysTimeformMonth)] + typePrice
  532. }
  533. fmt.Println(contractIds)
  534. // contractInId := strings.Join(contractIds, ",")
  535. if contractsType == 1 {
  536. list := s.contractReturnDao.GetInContractsIds(contractIds)
  537. for _, item := range list {
  538. typePrice := 0.00
  539. typePrice, _ = strconv.ParseFloat(item.Price, 64)
  540. totalTypePrice = totalTypePrice + typePrice
  541. fmt.Println(item)
  542. // :=decimal.NewFromFloat(typePrice)
  543. returnDate[item.Time.Format(conf.SysTimeformMonth)], _ = decimal.NewFromFloat(returnDate[item.Time.Format(conf.SysTimeformMonth)]).Add(decimal.NewFromFloat(typePrice)).Float64()
  544. }
  545. } else {
  546. list := s.contractPaidDao.GetInContractsIds(contractIds)
  547. for _, item := range list {
  548. typePrice := 0.00
  549. typePrice, _ = strconv.ParseFloat(item.Price, 64)
  550. totalTypePrice = totalTypePrice + typePrice
  551. returnDate[item.Time.Format(conf.SysTimeformMonth)], _ = decimal.NewFromFloat(returnDate[item.Time.Format(conf.SysTimeformMonth)]).Add(decimal.NewFromFloat(typePrice)).Float64()
  552. }
  553. }
  554. totalContractPrice, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", totalContractPrice), 64)
  555. totalTypePrice, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", totalTypePrice), 64)
  556. // ac := accounting.Accounting{Symbol: "", Precision: 2}
  557. surveryData := map[string]interface{}{
  558. "totalContractPrice": totalContractPrice,
  559. "totalContractPriceShow": totalContractPrice,
  560. // "totalReturnPrice": ac.FormatMoney(totalReturnPrice),
  561. "performNumber": performNumber,
  562. "closeNumber": closeNumber,
  563. "uncloseNumber": uncloseNumber,
  564. "returnDate": returnDate,
  565. }
  566. if contractsType == 1 {
  567. surveryData["totalReturnPriceShow"] = totalTypePrice
  568. } else {
  569. surveryData["totalPaidPriceShow"] = totalTypePrice
  570. }
  571. return surveryData
  572. }
  573. // 获得合同总数量和总金额
  574. func (s *contractService) getContractTotalAndPrice(bidsectionId int, projectId int, treeType int) (contractTotal int, priceTotal float64) {
  575. contractListAll := s.treeContractDao.GetContractAll(bidsectionId, projectId)
  576. // 获得收入合同
  577. contractList := s.treeContractDao.GetContract(bidsectionId, projectId, treeType)
  578. priceTotal = 0.00
  579. for _, item := range contractList {
  580. contractPrice, _ := strconv.ParseFloat(item.ContractPrice, 64)
  581. priceTotal = priceTotal + contractPrice
  582. }
  583. // 合同总数
  584. // contractTotal = len(contractList) + 1
  585. contractTotal = len(contractListAll)
  586. // 合同收入总金额
  587. // price, _ := strconv.ParseFloat(priceString, 64)
  588. // priceTotal = priceTotal + price
  589. // 保留2位小数
  590. priceTotal, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", priceTotal), 64)
  591. return contractTotal, priceTotal
  592. }
  593. // 构建合同详情视图
  594. func (s *contractService) makeContractVM(contract *models.CmContracts) viewmodels.Contracts {
  595. contractsVM := viewmodels.Contracts{}
  596. if contract.Id == 0 {
  597. return contractsVM
  598. }
  599. id, _ := comm.AesEncrypt(strconv.Itoa(contract.Id), conf.SignSecret)
  600. treeId, _ := comm.AesEncrypt(strconv.Itoa(contract.TreeId), conf.SignSecret)
  601. bidsectionId, _ := comm.AesEncrypt(strconv.Itoa(contract.BidsectionId), conf.SignSecret)
  602. contractsVM.Id = id
  603. contractsVM.TreeId = treeId
  604. contractsVM.ContractsType = contract.ContractsType
  605. contractsVM.BidsectionId = bidsectionId
  606. contractsVM.Name = contract.Name
  607. contractsVM.Content = contract.Content
  608. contractsVM.Code = contract.Code
  609. contractsVM.PartyA = contract.PartyA
  610. contractsVM.PartyASigner = contract.PartyASigner
  611. contractsVM.PartyB = contract.PartyB
  612. contractsVM.PartyBSigner = contract.PartyBSigner
  613. contractsVM.Remarks = contract.Remarks
  614. contractsVM.SettlementCode = contract.SettlementCode
  615. contractsVM.ContractDeductionTotal = contract.ContractDeductionTotal
  616. // price, _ := strconv.ParseFloat(contract.Price, 64)
  617. // returned, _ := strconv.ParseFloat(contract.Returned, 64)
  618. // paid, _ := strconv.ParseFloat(contract.Paid, 64)
  619. price, _ := strconv.ParseFloat(contract.Price, 64)
  620. // contractsVM.PriceFloat = price
  621. contractsVM.Price = price
  622. contractsVM.Returned = contract.Returned
  623. contractsVM.Paid = contract.Paid
  624. contractsVM.Status = contract.Status
  625. contractsVM.Locking = contract.Locking
  626. contractsVM.ContractDeductionTotal = contract.ContractDeductionTotal
  627. contractsVM.CreateTime = contract.CreateTime.Format(conf.SysTimeform)
  628. contractsVM.UpdateTime = contract.UpdateTime.Format(conf.SysTimeform)
  629. // nilTime := time.Time{}
  630. // contract.SignerTime != nilTime
  631. if !contract.SignerTime.IsZero() {
  632. contractsVM.SignerTime = contract.SignerTime.Format(conf.SysTimeform)
  633. }
  634. return contractsVM
  635. }