Загрузка данных
ПОИСК
динамические проверки и OR внутри AND
const crosses_count = await ViewContext.fields.price_lists.app.search().where((f,g)=>g.and(
f.__deletedAt.eq(null),
f.__id.neq(Context.id),
f.product.link(Context.data.product!),
f.price_list_type.link(Context.data.price_list_type!),
f.shipment_period.eq(Context.data.shipment_period!),
f.shipment_period_uom.eq(Context.data.shipment_period_uom!),
f.warranty_period.eq(Context.data.warranty_period!),
Context.data.price_id ? f.price_id.link(Context.data.price_id!) : f.price_id.eq(null),
g.or( g.and(f.date_from.lte(Context.data.date_from!),
f.date_to.gte(Context.data.date_from!)),
g.and(f.date_from.gte(Context.data.date_from!),
f.date_to.lte(Context.data.date_to!)),
g.and(f.date_from.gte(Context.data.date_from!),
f.date_from.lte(Context.data.date_to!)))
)).count();
-----------------------------------------------------------
динамический набор условий
Context.fields.filedname.data.setFilter(function(f,c,g){
let operands: Filter[] = [];
let operandsOr: Filter[] = [];
for (const position of Context.data.positions){
operandsOr.push(f.nomenclature_position.has(positions))
}
operands.push(g.or(...operandsOr));
operands.push(f.__deletedAt.eq(null));
if (Context.data.address)
operands.push(f.address.like(Context.data.address));
return g.and(...operands);
});
-----------------------------------------------------------
EQL
let productId = Context.data.productid!.id;
let projectId = Context.data.ProjectId!.id;
let lowThresholdDate = salesOrderIdItem.data.OrderDate.addDate(0,0,-93);
let codesArr:string[] = ['qwer','asdf','zxcv'];
let searchStr:string = "";
searchStr = "'" + codesArr.join("','") + "'";
let pp = await Context.fields.produkt_proekta.app.search().where(`
[__deletedAt] = NULL AND
[ProjectId] IN (SELECT [__id] FROM [test.leads] WHERE
[__id] = '${projectId}') AND
[code] IN (${searchStr}) AND
[PlannedEndDate]>'${lowThresholdDate.format()}' AND ((
NOT [Status] IN ('zakryt','zakryt_-_proigran')) OR [Status] = NULL) AND
[priceListProduct] IN (SELECT [__id] FROM [test.PriceListProduct] WHERE
[ProductId] IN (SELECT [__id] FROM [test.products] WHERE
[__id] = '${productId}')) AND
COUNT (FROM [mdm.Attachment] WHERE PARENT.[__id] in [RelatedToId]) > 0 AND
[__id] IN (SELECT [ContactId] FROM [mdm.Attachment])
`).first();
-----------------------------------------------------------
Поиск по дате-времени
truncateTime() не работает на некоторых версиях, вместо него использовать (new Datetime(`${(new Datetime()).getDate().format()}T00:00:00`))
Поиск StartDate<= TODAY <=EndDate
let todayLowThreshold = new Datetime();
let todayHighThreshold = (new Datetime(`${(new Datetime()).getDate().format()}T00:00:00`)).addDate(0,0,1);
[StartDate] <= '${todayHighThreshold.format()}' AND
[EndDate] >= '${todayLowThreshold.format()}' AND
EQL поиск не работает по приравниванию даты. Для поиска по совпадению с днем надо искать в интервале от (new Datetime(`${(new Datetime()).getDate().format()}T00:00:00`)) до (new Datetime(`${(new Datetime()).getDate().format()}T00:00:00`)).addDate(0,0,1)
Поиск по подтипу "дата":
let today_date = (new Datetime()).getDate();
EQL нужно учитывать время (см выше), т.е строка [data] >= '2025-07-08' сработает, а [data] <= '2025-07-08' не включит крайнее значение
SDK не учитывает время, можно использовать f.data.gte(today_date) и f.data.lte(today_date)
today_date.format() выведет '2025-07-08'
Расчет количества рабочих дней
const start = Context.data.data!.asDatetime(new TTime(0,0,0,0));
const end = (new Datetime(`${(Context.data.data_vremya!).getDate().format()}T00:00:00`)).addDate(0,0,1);
const time = await System.productionSchedule.getWorkingTime(start,end);
ViewContext.data.kolichestvo_rabochikh_dnei = Math.ceil(time.hours / 8);
-----------------------------------------------------------
api фильтра в методе seach
// Для создания кастомного фильтра
class PhoneFilter {
constructor (private filter: any) {
}
json () {
return this.filter;
}
}
//** Функция для вычисление номеров телефонов по контактам */
async function getContactsPhone(phone_tel: string) {
const contacts = await Context.fields.contact.app.search()
.where((f,g) => g.and(
f.__deletedAt.eq(null),
(f as any)["_phone"].neq(null))
)
.where(f => new PhoneFilter(
{"tf":
{
"_phone": phone_tel
}
}
))
.all();
}
Чтобы корректно сформировать запрос нужно использовать список полей доступных для фильтрации: https://api.elma365.com/ru/public-api/guides/Filter/
А тут можно найти пример от элмы. https://community.elma365.com/ru/threads/66/ - там же поиск по множественному полю типа приложение
-----------------------------------------------------------
поиск более 10к объектов
const orders_search = Context.fields.orders.search().where((f,g) => g.and());
let count = await orders_search.count();
let orders = await orders_search.size(10000).all();
if (count > 10000){
for (let i = 1; ; i++) {
const orders_slice = await orders_search.size(10000).from(10000 * i).all();
if (orders_slice){
orders = orders.concat(orders_slice);
if (orders_slice.length < 10000) {
break;
}
}else{
break;
}
}
}
-----------------------------------------------------------
поиск через линк когда есть массив id
async function getContactIdsDuplicatesOnAnotherTarget(contactIds: string[]) {
const lookups = (contactIds as any) as Array<ApplicationItemRef<Application$_clients$_contacts$Data, Application$_clients$_contacts$Params>>;
f.ContactId.link(lookups),