Power Apps Canvas: інвентаризація. Робота зі сканером.

Під час розробки додатку для інвентаризації речей на складі для благодійної організації, ми вирішили розробляти функціонал за допомогою 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')})

Коротке демо 🙂

Отже, ми розглянули роботу зі сканером, обробку колекції, її редагування та запис данихв таблицю на прикладі додатку з інвентаризації.