Під час розробки додатку для інвентаризації речей на складі для благодійної організації, ми вирішили розробляти функціонал за допомогою Power Apps Canvas. Ця low-code платформа заощадила час на самій розробці та дала можливість почати користуватися застосунком за кілька днів.
В цій статті, я хочу поділитися інформацією щодо рішення для інвентаризації, а деякі елементи є універсальними, тож ви зможете знайти їм застосування для канвасних додатків іншого призначення.
Почнемо зі схеми даних. Головна таблиця – Products. В ній основні поля це Name та Barcode. Також є поля для визначення категорії.
Наступна таблиця – Inventory. В ній є лукап на Product, поле для визначення одиниці виміру – Unit, кількість доступних одиниць та кількість зарезервованих.
Інвентаризація розділена на дві частини – для роботи з товарами зі штрих-кодом та без.

Розглянемо пошук товару по штрихкоду.
Для цього я додала алемент Barcode Scanner. При натисканні відкривається вікно камери і можна зчитати штрихкод. Результуюче значення можна дістати за допомогою атрибуту Value:

btnItemBarcodeScanner.Value

Після сканування в лейблі можна побачити значення штрихкоду. Далі необхідно зрозуміти, чи був знайдений продукт з таким штрихкодом. Для цього користувачу виводиться або повідомлення, що такого товару нема, або виводиться список пов’язаних записів з Inventory таблиці, де можна побачити одиниці виміру та доступну кількість варіантів цього продукту.

Для цього, на кнопку скану налаштований параметр OnScan:
If(
!IsEmpty(Filter(Products,Barcode=btnItemBarcodeScanner.Value)),
UpdateContext({
isProductFound: true,
productRecord: First(Filter(Products,Barcode=btnItemBarcodeScanner.Value))
});
ClearCollect(InventoryByBarcodeCollection, Filter(Inventories, Product.Barcode=btnItemBarcodeScanner.Value)),
UpdateContext({
isProductFound: false,
productRecord:Blank()
});
Clear(InventoryByBarcodeCollection)
);
Локальна змінна isProductFound використовується для відображення повідомлення, що продукт не знайдений, якщо в таблиці Product нема такого продукту. Або, щоб заховати це повідомлення і показати Inventory записи, якщо такий продукт є.
Локальна змінна productRecord потрібна для відображення списку цих самих Inventory записів.
Колекція InventoryByBarcodeCollection необхідна для редагування доступної кількості товарів в таблиці Inventory з можливістю відміни цих редагувань (на випадок помилкових дій).
Отже, далі відображається галерея, що складається з рядків цієї колекції:

Для кожного рядку колекції – маємо дві лейбли для відображення назви інвенторі та юніт (одиниці виміру): ThisItem.Name та ThisItem.Unit:

Далі цікава частина для роботи з кількістю товару. При скануванні, якщо товар знайдений – для кожного інвенторі запису відображається поточна доступна кількість товару. Для цього, Default параметр встановлений відображати ThisItem.’Available Qty’. Але для збільшення і зменшення кількості товарів треба правильно налаштувати процес оновлення записів, щоб зміни в одному інвенторі не перезатирали зміни в іншому.
Для цих цілеї дуже підходить колекція. Тому, на натискання “+” кнопки встановлена така функція:
UpdateIf(InventoryByBarcodeCollection, Inventory=ThisItem.Inventory,
{
'Available Qty':ThisItem.'Available Qty'+1
})
;
Перший параметр функції UpdateIf – колекція, в якій треба знайти рядок за допомогою фільтру в другому параметрі. Ну і самі зміни робляться по аналогії з функцією Patch в третьому параметрі.
Якщо зміни робляться за допомогою прямого запису нового значення – то необіхдно задати поведінку через OnChange атрибут:

Всі ці зміни ваються в колекції, а не напряму в таблиці. Тому, щоб зберегти зміни в таблицю – необхідно налаштувати кнопку збереження змін. Я це роблю за домогою Patch функції:
Patch(Inventories, LookUp(Inventories,Inventory=ThisItem.Inventory),{'Available Qty':ThisItem.'Available Qty'})

І налаштуємо DisplayMode, щоб кнопка була доступна тільки якщо вносилися зміни:

Таке саме налаштування DisplayMode для кнопки відміни змін. Ну і потрібно додати OnSelect для кнопки затирання змін:

В даному випадку різниця з кнопкою збереження полягає в тому, що тут використовується UpdateIf колекції, в базу зміни не йдуть. А для кнопки збереження зміни зберігаються одразу в таблицю датаверсу.
UpdateIf(InventoryByBarcodeCollection, Inventory=ThisItem.Inventory, {'Available Qty':LookUp(Inventories,Inventory=ThisItem.Inventory,'Available Qty')})
Коротке демо 🙂
Отже, ми розглянули роботу зі сканером, обробку колекції, її редагування та запис данихв таблицю на прикладі додатку з інвентаризації.