package amo import "surdeus.su/core/ss/urlenc" import "fmt" // The type describes tuple // contaning everything related // to THE lead. type LeadTuple struct { Lead *Lead `json:"lead,omitempty"` MainContact *Contact `json:"main_contact,omitempty"` Company *Company `json:"company,omitempty"` } func (client *Client) GetLeadTuples( opts ...urlenc.Builder, ) ([]LeadTuple, NextFunc[[]LeadTuple], error) { opts = append( opts, urlenc.Value[string]{"with", "contacts"}, ) res := fmt.Sprintf( "/api/v4/leads?%s", urlenc.Join(opts...).Encode(), ) return client.GetLeadTuplesByURL(res) } func (client *Client) GetLeadTuplesByURL( u string, ) ([]LeadTuple, NextFunc[[]LeadTuple], error) { return client.getLeadTuplesByFuncURL( func() ([]Lead, NextFunc[[]Lead], error){ return client.GetLeadsByURL(u) }, ) } func (client *Client) getLeadTuplesByFuncURL( // The function describes way of getting leads. callback func() ( []Lead, NextFunc[[]Lead], error, ), ) ([]LeadTuple, NextFunc[[]LeadTuple], error) { var fn NextFunc[[]LeadTuple] leads, next, err := callback() if err != nil { return nil, nil, fmt.Errorf("amo.GetLeads(...): %s\n", err) } comIDs := []int{} contactIDs := []int{} leadToCom := map[int]int{} leadToContact := map[int]int{} for _, lead := range leads { coms := lead.Embedded.Companies if len(coms) > 0 { com := coms[0] leadToCom[lead.ID] = com.ID comIDs = append(comIDs, com.ID) } mainContact, hasMain := lead.Embedded. Contacts.GetMain() if hasMain { leadToContact[lead.ID] = mainContact.ID contactIDs = append(contactIDs, mainContact.ID) } } comMap := map[int] *Company{} var coms []Company if len(comIDs) > 0 { coms, _, err = client.GetCompanies( urlenc.Array[int]{ "id", comIDs, }, ) if err != nil { return nil, nil, fmt.Errorf( "amo.GetCompanies(...): %s\n", err) } for i := range coms { comMap[coms[i].ID] = &coms[i] } } contactMap := map[int] *Contact{} var contacts []Contact if len(contactIDs) > 0 { contacts, _, err = client.GetContacts( urlenc.Array[int]{ "id", contactIDs, }, ) if err != nil { return nil, nil, fmt.Errorf( "client.GetContacts(...): %s\n", err) } } for i := range contacts { contactMap[contacts[i].ID] = &contacts[i] } ret := []LeadTuple{} for i := range leads { leadID := leads[i].ID tup := LeadTuple{ Lead: &leads[i], } contactID, ok := leadToContact[leadID] if ok { contact, ok := contactMap[contactID] if ok { tup.MainContact = contact } } companyID, ok := leadToCom[leadID] if ok { company, ok := comMap[companyID] if ok { tup.Company = company } } ret = append(ret, tup) } if next != nil { fn = NextFunc[[]LeadTuple]( func() ([]LeadTuple, NextFunc[[]LeadTuple], error) { return client.getLeadTuplesByFuncURL( next, ) }, ) } return ret, fn, nil }