amocrm-client
Version:
JS Library for AmoCRM
65 lines (54 loc) • 3.29 kB
text/typescript
import { IResourceEntityWithEmbedded } from "../../../interfaces/api";
import { TConstructor, TEntityEmbeddedConstructor } from "../../../types";
import { IRequestOptions } from "../../../interfaces/common";
import { ICanGetByIdFactory } from "../../factories/mixins/hasGetById";
import { ResourceCollection } from "../../ResourceCollection";
import { ContactCriteria } from "../../../interfaces/contact";
import { IContactFactory, ContactFactory } from "../../factories/ContactFactory";
import { Contact, IContact } from "../Contact";
interface IEmbeddedWithContacts {
contacts: ResourceCollection<IContact>
}
export interface IHasContactsEntity<T extends ICanGetByIdFactory<IResourceEntityWithEmbedded<T>>> extends IResourceEntityWithEmbedded<T> {
contacts(criteria?: Pick<ContactCriteria, "with">, options?: IRequestOptions): Promise<IContact | false>;
}
export function hasContacts<T extends ICanGetByIdFactory<IResourceEntityWithEmbedded<T>>>(Base: TEntityEmbeddedConstructor<T>): TConstructor<IResourceEntityWithEmbedded<T>> {
return class HasContacts extends Base {
async contacts(criteria?: Partial<Pick<ContactCriteria, "with">>, options?: IRequestOptions) {
let _embedded = this._embedded;
if (!this._embedded && !this.id) return false;
if (this.id && !this._embedded) {
const entity = await (this.getFactory() as T).getById(this.id, { with: "contacts" });
if (entity == null) return false;
_embedded = entity._embedded;
}
const embeddedContacts = (_embedded as IEmbeddedWithContacts).contacts;
if (embeddedContacts.size() === 0) return [];
if (Object.keys(embeddedContacts.first() || {}).length > 5) return embeddedContacts;
const contactIds: number[][] = new ResourceCollection(embeddedContacts.pluck('id')).chunk(250).all();
const contacts: ResourceCollection<IContact> = new ResourceCollection([]);
const contactFactory: IContactFactory = new ContactFactory(this.getFactory().getRequest());
for (const ids of contactIds) {
const mergedCriteria = Object.assign(criteria || {}, { filter: { id: ids }, limit: 250 }) as Partial<ContactCriteria>;
const pagination = await contactFactory.get(mergedCriteria, options);
contacts.add(pagination.getData().all());
if (!pagination.hasNext() || pagination.getData().size() < 250) continue;
let hasNextPage = true;
do {
const nextPage = await pagination.next();
if (nextPage != false) contacts.add(nextPage);
else hasNextPage = false;
} while (hasNextPage);
}
contacts.each((contact: IContact) => {
embeddedContacts.each((embeddedContact) => {
if (embeddedContact.id! == contact.id!) {
contact.is_main = embeddedContact.is_main;
}
});
});
(this._embedded as IEmbeddedWithContacts).contacts = contacts;
return contacts;
}
};
}