Link

3. Отчет по доходам

Для создания отчета по доходам нам будет достаточно изменить только клиентское приложение.

Отчет будет отражать все доходы сгруппированные по статьям доходоа. Визуализировать данные будем с помощью таблицы.

Создадим форму отчета, добавим класс в клиентское приложение и пункт в меню.

forms/IncomeReport.js

import { Elements, Form } from 'katejs/lib/client';

export default class IncomeReport extends Form {
  constructor(args) {
    super(args);
    this.elements = [
      {
        type: Elements.LABEL,
        tag: 'h2',
        title: 'Income report',
      },
    ];
  }
}

AppClient.js


....
import IncomeReport from './forms/IncomeReport';

const AppClient = parent => class Client extends use(parent) {
  static title = title;

  constructor(params) {

    ...

    this.forms = {
      ...
      IncomeReport,
    };
    this.menu.push({
      form: 'IncomeReport',
      title: 'Income report',
    });
  }
};

Сейчас форма нашего отчета отображает только заголовок. Добавим в элементы кнопку для формирования отчета и таблицу, в которой будут выводится данные

import { Elements, Form } from 'katejs/lib/client';

export default class IncomeReport extends Form {
  constructor(args) {
    super(args);
    this.elements = [
      {
        type: Elements.LABEL,
        tag: 'h2',
        title: 'Income report',
      },
      {
        type: Elements.BUTTON,
        title: 'Form report',
        onClick: this.formReport,
      },
      {
        id: 'data',
        type: Elements.TABLE,
        columns: [
          {
            title: 'Article',
            dataPath: 'article',
          },
          {
            title: 'Sum',
            dataPath: 'sum',
          },
        ],
      },
    ];
  }

  formReport = () => {
    console.log('form report');
  }
}

Обратите внимание, что обработчик кнопки мы оформили как свойство экземпляра формы, а не как метод класса. Так нужно для того, чтобы сохранился контекст this т.к. функция будет вызвана как обработчик нажатия кнопки.

Для получения данных сделаем запрос - выборку - к сущности Article. В нашем отчете нам нужно сгруппировать по статье и получить сумму.

  formReport = async () => {
    const { response: data } = await this.app.Income.query({
      attributes: [
        [{ $func: { fn: 'SUM', col: 'sum' } }, 'sum'],
      ],
      group: [{ $col: 'article.uuid' }],
      limit: -1,
    });
    this.content.data.value = data;
  }

Мы добавили ключевое слово async чтоб можно было воспользоваться асинхронными вызовами. Полученные данные мы устанавливаем в значение таблицы.

Синтаксис атрибутов метода query практически идентичен синтаксису выборок элементов ORM Sequelize.

Параметр limit нужен для отключения автоматической пагинации.

При таком запросе мы получим массив объектов, где article это объект - ссылка на статью с полями uuid иtitle. Нас интересвет именно title поэтому нам надо поправить атрибут dataPath у первой колонки таблицы

      {
        id: 'data',
        type: Elements.TABLE,
        columns: [
          {
            title: 'Article',
            dataPath: 'article.title',
          },

Отчет готов!

Разумеется, отчет должен формироваться по периоду. Его лего доделать, добавив на форму элементы типа DATE для начала и окончания периода и передать их в запрос query в атрибуте where.

Код

Изменения, внесенные на данном этапе: 3. Income report

Код данного этапа можно посмотреть по тэгу step-3:

git checkout step-3