Цель:
в раздел «Платежи», загруженный из ELMA365 Store, добавить страницу «Платежи на сегодня», на которой специалист по платежам (казначей) будет видеть все предстоящие платежи (из приложения «Заявки на расход ДС») на сегодня, сгруппированные по статусу, и иметь возможность вернуть отдельные платежи на корректировку либо выбрать несколько платежей и перенести их на другой день.
Решение:
1) Создать в разделе «Платежи» страницу «Платежи на сегодня» и разместить там виджет «Динамический список», в него будет передаваться таблица тех статусов, в которых находятся сегодняшние платежи – для создания подзаголовков таблицы с платежами.
2) В виджет «Динамический список» поместить пользовательский виджет «Платежи в статусе» для отображения только тех платежей, которые находятся в соответствующем статусе Динамического списка из п.1.
Добавить в пользовательский виджет еще один «Динамический список», в который будет передаваться таблица платежей.
3) В этот (второй) Динамический список добавить еще один пользовательский виджет «Данные по заявке», в котором будут отображаться данные по заявке на платеж.
Вот так эта страница выглядит в готовом виде:
Для удобства можно свернуть панель с платежами в каком-либо из статусов (на рисунке выше свернуты платежи в статусе «Согласовано»).
Шаги реализации решения:
Схематично изобразим эту матрешку:
На рисунке цифрами обозначены передаваемые данные из одного виджета в другой (их описание будет дальше).
Процесс
Для начала в приложении «Заявки на расход ДС» создадим процесс для переноса платежей на другую дату. Так его и назовем, «Перенести платежи» (код процесса «shift_payments»).
Страница «Платежи на сегодня»
1. Создадим в разделе «Платежи» страницу «Платежи на сегодня». Перейдем в конструктор и откроем вкладку «Контекст».
2. Создадим в контексте формы следующие свойства:
В настройках Таблицы статусов создадим только одну колонку типа «Данные», тип данных «Строка», имя свойства «Статус платежа», код «payment_status».
Перейдем на вкладку «Сценарии» и добавим следующий код:
Код:
declare const alert: any;
declare const console: any;
async function onInit() { // Объявим функцию, выполняемую при инициализации формы
// Заполним таблицу "Таблица статусов" из контекста формы для генерации динамического списка, и затем посчитаем итоговую сумм
Context.data.shifted_payments = {}; // В переменной произвольного типа создадим пустой объект, куда затем будем записывать идентификаторы платежей, которые необходимо перенести на другой день
const today = new TDate();
const today_payments = await Namespace.app.payment_request.search() // С помощью методов search().where() найдем сегодняшние платежи и с помощью метода all() получим данные этих элементов
.where((f, g) => g.and(
// f.payment_desired_date.eq(today),
f.__deletedAt.eq(null),
))
.size(10000)
.all();
if (today_payments && today_payments.length > 0) {
Context.data.payments = today_payments; // Все найденные платежи запишем в контекстную переменную
let statuses_array: {index: number, name: string}[] = []; // Объявим массив объектов для записи номера и названия статуса
for (let payment of today_payments) {
if (statuses_array && statuses_array.length > 0) { // Из каждого платежа на сегодня запишем статус в объект уникальных значений со свойствами "index" (порядковый номер статуса) и "name" (название статуса)
if (statuses_array.some(i => i.index === payment.data.__status!.index) === false) {
statuses_array.push({ index: payment.data.__status!.index, name: payment.data.__status!.name });
}
} else {
statuses_array.push({ index: payment.data.__status!.index, name: payment.data.__status!.name });
}
}
statuses_array.sort((a, b) => a.index > b.index ? 1 : -1); // Отсортируем полученные объекты по порядковому номеру статуса
for (let item of statuses_array) { // Запишем названия статусов в Таблицу статусов из контекста формы
const row = Context.data.statuses_table!.insert();
row.payment_status = item.name;
}
Context.data.statuses_table = Context.data.statuses_table; // Сохраним изменения в таблице статусов
let total_sum = today_payments.reduce((sum, current) => sum + (current.data.payment_amount ? current.data.payment_amount.asFloat() : 0), 0); // Посчитаем общую сумму платежей на сегодня
let sum_match = total_sum.toString().match(/^(.*?)((?:[,.]\d+)?|)$/); // Дальнейшие преобразования - для красивого отображения суммы в строке текста
let sum_string = '';
if (sum_match) {
sum_string = sum_match[1].replace(/\B(?=(?:\d{3})*$)/g, ' ') + sum_match[2];
} else {
sum_string = total_sum.toString();
}
Context.data.total = `Платежей на сегодня итого на сумму: ${sum_string} руб.`;
} else {
Context.data.total = `На сегодня платежи не запланированы.`;
}
}
async function shift(): Promise<void> { // Объявим функцию для переноса платежей на другой день
const payments_id_list = Context.data.shifted_payments;
const payments_to_be_shifted_ids: string[] = [];
for (let id in payments_id_list) { // Запишем массив id тех платежей, которые нужно перенести на другой день
payments_to_be_shifted_ids.push(payments_id_list[id])
}
console.log(payments_to_be_shifted_ids);
if (payments_to_be_shifted_ids.length === 0) { // Выведем на экран сообщение об отсутствии выбранных платежей
alert('Не выбраны платежи');
return;
}
if (!Context.data.new_payment_date) {
alert('Не указана новая дата оплаты'); // Выведем на экран сообщение о том, что не указана дата, на которую нужно перенести платеж
return;
}
const new_date = Context.data.new_payment_date.asDatetime(new TTime(0, 0, 0, 0)); // Преобразуем новую дату платежа в формат TDatetime
if (payments_to_be_shifted_ids && payments_to_be_shifted_ids.length > 0 && Context.data.new_payment_date) { // Запустим процесс переноса платежей на другой день. Передадим в процесс по переносу платежей id выбранных элементов и новую дату платежа
let inputData: Process$payment$payment_request$shift_payments$Context$$Data = {
payment_date: (new_date.format() as any) as TDate,
payments: payments_to_be_shifted_ids.map((item: any) => ((item as any) as ApplicationItemRef<Application$payment$payment_request$Data, Application$payment$payment_request$Params>)),
}
await Context.fields.payments.app.processes.shift_payments.run(inputData);
}
}
На вкладку «Шаблон» вынесем свойство «Новая дата платежа».
Добавим виджет «Кнопка», назовем ее «Перенести дату». Тип действия выберем «Сценарий», и в «Событии при нажатии» выберем функцию «shift», чтобы при нажатии на кнопку запускался скрипт запуска процесса «Перенести платежи» по выбранным платежам.
Первый динамический список - группировка
Добавим на страницу виджет «Панель с заголовком», заголовок можно не указывать – поставить пробел. В Этот виджет положим виджет «Динамический список» (собственно, панель с заголовком нам была нужна для того, чтобы динамический список выглядел красиво).
В настройках динамического списка в качестве списочных данных выберем таблицу из контекста формы «Таблица статусов».
Ниже динамического списка разместим виджет «Надпись», в котором текст свяжем с переменной «Платежей на сегодня итого на сумму:». Итоговая сумма будет вычисляться в сценарии, в функции onInit(), которая выполняется при открытии страницы.
Теперь сохраним все изменения в конструкторе страницы и вернемся в раздел «Платежи».
Второй динамический список
В настройках раздела «Платежи» (шестеренка) выберем пункт выпадающего меню «Интерфейсы» и создадим пользовательский виджет. Назовем его «Платежи в статусе».
Откроем вкладку «Контекст» и создадим переменные с такими настройками:
Продолжение статьи см.в комментариях.