lead-tuple.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. package amo
  2. import "surdeus.su/core/ss/urlenc"
  3. import "fmt"
  4. // The type describes tuple
  5. // contaning everything related
  6. // to THE lead.
  7. type LeadTuple struct {
  8. Lead *Lead `json:"lead,omitempty"`
  9. MainContact *Contact `json:"main_contact,omitempty"`
  10. Company *Company `json:"company,omitempty"`
  11. }
  12. func (client *Client) GetLeadTuples(
  13. opts ...urlenc.Builder,
  14. ) ([]LeadTuple, NextFunc[[]LeadTuple], error) {
  15. opts = append(
  16. opts, urlenc.Value[string]{"with", "contacts"},
  17. )
  18. res := fmt.Sprintf(
  19. "/api/v4/leads?%s",
  20. urlenc.Join(opts...).Encode(),
  21. )
  22. return client.GetLeadTuplesByURL(res)
  23. }
  24. func (client *Client) GetLeadTuplesByURL(
  25. u string,
  26. ) ([]LeadTuple, NextFunc[[]LeadTuple], error) {
  27. return client.getLeadTuplesByFuncURL(
  28. func() ([]Lead, NextFunc[[]Lead], error){
  29. return client.GetLeadsByURL(u)
  30. },
  31. )
  32. }
  33. func (client *Client) getLeadTuplesByFuncURL(
  34. // The function describes way of getting leads.
  35. callback func() (
  36. []Lead,
  37. NextFunc[[]Lead],
  38. error,
  39. ),
  40. ) ([]LeadTuple, NextFunc[[]LeadTuple], error) {
  41. var fn NextFunc[[]LeadTuple]
  42. leads, next, err := callback()
  43. if err != nil {
  44. return nil, nil, fmt.Errorf("amo.GetLeads(...): %s\n", err)
  45. }
  46. comIDs := []int{}
  47. contactIDs := []int{}
  48. leadToCom := map[int]int{}
  49. leadToContact := map[int]int{}
  50. for _, lead := range leads {
  51. coms := lead.Embedded.Companies
  52. if len(coms) > 0 {
  53. com := coms[0]
  54. leadToCom[lead.ID] = com.ID
  55. comIDs = append(comIDs, com.ID)
  56. }
  57. mainContact, hasMain := lead.Embedded.
  58. Contacts.GetMain()
  59. if hasMain {
  60. leadToContact[lead.ID] = mainContact.ID
  61. contactIDs = append(contactIDs, mainContact.ID)
  62. }
  63. }
  64. comMap := map[int] *Company{}
  65. var coms []Company
  66. if len(comIDs) > 0 {
  67. coms, _, err = client.GetCompanies(
  68. urlenc.Array[int]{
  69. "id",
  70. comIDs,
  71. },
  72. )
  73. if err != nil {
  74. return nil, nil, fmt.Errorf(
  75. "amo.GetCompanies(...): %s\n", err)
  76. }
  77. for i := range coms {
  78. comMap[coms[i].ID] = &coms[i]
  79. }
  80. }
  81. contactMap := map[int] *Contact{}
  82. var contacts []Contact
  83. if len(contactIDs) > 0 {
  84. contacts, _, err = client.GetContacts(
  85. urlenc.Array[int]{
  86. "id",
  87. contactIDs,
  88. },
  89. )
  90. if err != nil {
  91. return nil, nil, fmt.Errorf(
  92. "client.GetContacts(...): %s\n", err)
  93. }
  94. }
  95. for i := range contacts {
  96. contactMap[contacts[i].ID] = &contacts[i]
  97. }
  98. ret := []LeadTuple{}
  99. for i := range leads {
  100. leadID := leads[i].ID
  101. tup := LeadTuple{
  102. Lead: &leads[i],
  103. }
  104. contactID, ok := leadToContact[leadID]
  105. if ok {
  106. contact, ok := contactMap[contactID]
  107. if ok {
  108. tup.MainContact = contact
  109. }
  110. }
  111. companyID, ok := leadToCom[leadID]
  112. if ok {
  113. company, ok := comMap[companyID]
  114. if ok {
  115. tup.Company = company
  116. }
  117. }
  118. ret = append(ret, tup)
  119. }
  120. if next != nil {
  121. fn = NextFunc[[]LeadTuple](
  122. func() ([]LeadTuple, NextFunc[[]LeadTuple], error) {
  123. return client.getLeadTuplesByFuncURL(
  124. next,
  125. )
  126. },
  127. )
  128. }
  129. return ret, fn, nil
  130. }