Свої скрипти, без свого сервера
UGLAScript — мова зі статичною типізацією й середовище для неї всередині UGLA. Звіти, розрахунки, сповіщення й файли пишуть в IDE в самій системі, а запускаються вони за розкладом, на подію чи як власний метод API, поруч із вашими даними й без власного сервера.
UGLAScript
Для всіх галузей

/// A VAT summary for 30 days, as a PDF, sent by email.
import { byEntity } from "ugla/reports/vat/main";
const string RECIPIENT = "finance@example.test";
const int ARCHIVE = 169;
const string ZONE = "Europe/Kyiv";
export bool main(date asOf) {
date to = today(zoneOf(ZONE)) ?? asOf;
date from = plusDays(to, -30) ?? to;
string period = text(from) + " to " + text(to);
// Each legal entity pays VAT on its own:
// the report clamps every one before the total.
var rows = byEntity(from, to, null, null, null);
string pdf = renderPDF(
"<h1>VAT summary</h1><p>" + period + "</p>" + table(rows),
"VAT summary"
);
string file = "vat-summary-" + text(to) + ".pdf";
// Filed first, sent second: if the mail fails, the file exists.
diskWriteBytes(ARCHIVE, file, pdf);
return sendEmailWithFile(
RECIPIENT,
"VAT summary " + period,
"<p>The VAT summary is attached.</p>",
file,
pdf
);
}
string table(List<{
entity: string, entityID: int?, entityHref: string,
currency: string, obligations: decimal, credit: decimal,
toPay: decimal, creditReserve: decimal
}> rows) {
string body = "";
for (r in rows) {
body = body + "<tr><td>" + r.entity + "</td><td>"
+ text(round(r.toPay, 2)) + "</td><td>" + r.currency
+ "</td></tr>";
}
return "<table><tr><th>Entity</th><th>To pay</th><th></th></tr>"
+ body + "</table>";
}- Імпортує готовий звіт ПДВ, тож цифри ті самі, що на екрані, і кожна юрособа рахується окремо.
- Формує PDF, кладе його в архів на Диску й надсилає поштою.
- Запускається за розкладом, а кінець періоду можна передати параметром.
- Бачить і робить лише те, що дозволено IAM ролі, від імені якої працює.
/// A Disk folder for every legal entity, then a notification.
import { Entity } from "ugla/models/restaurants";
import { DiskDirectory } from "ugla/models/general";
[Notifies("entity-folders", "Entity folders", "")]
export int main(date asOf) {
string day = text(today(zoneOf("Europe/Kyiv")) ?? asOf);
int made = 0;
// Reading: rows arrive as records, every column checked
// against the live schema when the script compiles.
var entities = from x in Entity
where x.exist == true
select { name: x.name };
for (e in entities) {
// Writing: a new row is a handle until save() stores it.
var folder = DiskDirectory.create();
folder.name = e.name + " " + day;
folder.save();
made++;
}
sendNotification(
[1],
"Entity folders",
text(made) + " folders made for " + day + ".",
"entity-folders"
);
return made;
}- Читає юрособи запитом, і кожне поле звіряється зі структурою даних ще під час компіляції.
- Створює й зберігає нові записи через ту саму модель даних, що й інтерфейс.
- Надсилає бухгалтеру сповіщення з підсумком.
- Запис даних потребує окремого дозволу, який надають свідомо.
Що вміє модуль
IDE в системі
Скрипти пишуть, перевіряють і тестують у вбудованій IDE, у тій самій UGLA, де вони працюють.
За розкладом і на подію
Скрипт запускається за розкладом або на подію в системі, без сервера, відкритої адреси в інтернеті чи ключа до UGLA.
Сповіщення, файли й листи
Скрипт надсилає сповіщення, формує файли й відправляє їх e-mail.
Власні методи API
За потреби скрипт публікують як власний метод API: розгортання робить його доступним через публічну точку UGLAQL за API-ключем, зі своїм обробником і відповіддю, і з правами IAM ролі, від імені якої він працює.
Бінарні дані
Не лише текст і числа: скрипт працює і з бінарними даними, як-от PDF чи зображення.
Там, де конструктора замало
Цифра з умовою, таблицею відповідностей чи арифметикою, якої немає в конструкторі звітів, і логіка, спільна для кількох звітів.
Перевірка до запуску
Скрипт звіряється з реальною структурою ваших даних: перейменоване поле зупинить його ще до запуску, а не дасть порожню цифру у звіті.
Точні гроші
Дробові числа за замовчуванням точні, а не з плаваючою комою, тож копійки не губляться.
Ізольовано
Скрипт не відкриває файлів на сервері, мережевих з'єднань чи процесів: він робить лише те, що дозволяє мова, а листи й файли йдуть через UGLA.
Стовпцями, поруч із даними
Агрегації рахуються стовпцями, тож мільйон рядків обробляється всередині UGLA швидко й без вивантаження.
Тести
Бібліотеки скриптів мають власні тести, форматування й перевірку стилю.
ПДВ холдингу
Кожна юрособа платить ПДВ окремо, тож підсумок холдингу рахується по кожній, і переплата однієї не перекриває борг іншої. Підсумок звичайного звіту такого не порахує, а скрипт рахує.
Куди йдуть дані далі
Модуль не живе окремо: те, що в ньому сталося, одразу бачать інші.
Часті питання
Чим скрипт відрізняється від зовнішньої інтеграції?
Зовнішня програма працює поза UGLA й бачить дані лише через API. Скрипт працює всередині: поруч із даними, з перевіркою на їхній структурі, за розкладом, на подію чи на запит, без сервера, який треба тримати. А коли дані потрібні іншій системі, скрипт можна опублікувати як власний метод API, доступний через UGLAQL за API-ключем.
Де пишуть скрипти?
У вбудованій IDE, в самій UGLA: там скрипт пишуть, перевіряють на структурі ваших даних і тестують.
