Skip to content

Instantly share code, notes, and snippets.

@ildar2
Created June 25, 2020 11:57
Show Gist options
  • Save ildar2/b2198a37952dd0e96d1e20dcfefdfa5d to your computer and use it in GitHub Desktop.
Save ildar2/b2198a37952dd0e96d1e20dcfefdfa5d to your computer and use it in GitHub Desktop.
package infin.api.core.legal.entities.documents.demands.create
import androidx.annotation.Keep
import com.google.gson.annotations.SerializedName
import infin.api.core.legal.entities.Translation
/**
* Конструктор поля в заявлениях
*/
@Keep
data class DemandTypeField(
val id: Long?,
val deleted: Any?,
val required: Boolean,
val editable: Boolean,
/**
* Обозначает, что поле можно редактировать
* true = поле read-only
* false или null = поле editable
*/
val isValueEditable: Boolean?,
/**
* Скрывать поле у пользователя
*/
val isHidden: Boolean?,
val isUserTable: Boolean,
val isCustomerData: Any?,
val translations: Translation?,
val translationKey: String?,
val templateId: Any?,
val code: String?,
val length: Any?,
/**
* Тип поля
*/
val dataTypeId: Int,
val dataType: String?,
val dataTypeEnum: String?,
val selectSourceId: Long?,
val selectSourceName: Any?,
val selectSourceTable: String?,/** Имя таблицы (справочник) на который ссылается селектор**/
val value: String?,
val valueDataType: String?,
val autofillValue: String?,
/**
* Только для [TYPE_FORMULA]
*
* Рекурсивное выражение формулы
* она не очень сложная, обычно просто вычесть из одной даты другую
*/
val formulaExpression: FormulaExpression?,
/**
* Только для [TYPE_SWITCHER]
*
* Список инструкций для отображения полей
* в зависимости от условий
*/
val switcherView: List<SwitcherInstruction>?,
val parent: Any?,
val name: String?,
val data: Any?,
val label: String?,
val priority: Any?,
/**
* Дополнительные данные для валидации этого поля
*/
val constraints: List<Constraint>?,
/**
* Только для [TYPE_INPUT_FILE]
*
* Список файлов-образцов, которые юзер должен скачать, заполнить и загрузить обратно
* id загруженных файлов записываются в [value] через запятую
*/
val attachedFiles: List<AttachedFile>?,
val lowerBound: Any?,
val upperBound: Any?,
val multiplicity: Any?,
/**
* Только для [TYPE_STATIC_DEPENDENT]
*
* ссылка на поле, при изменении которого должны запрашиваться данные
* чтобы заполнить это поле
*/
val parentId: Long?,
val dataSourceFieldId: Any?,
val fileTypeId: Any?,
val demandRequestCode: Any?,
val fileExportPath: Any?,
/**
* Использовать ли [RowItemType.INPUT_AMOUNT] для поля ввода
* true означает, что нужно подставлять пробелы в числа при вводе, например "10 000"
*/
val withDelimiter: Boolean?,
val mask: Any?,
/**
* Только для [TYPE_REQUEST_TRIGGER]
* Маппинг полей [id] с [TriggerField.id] для [demandRequest]
*/
val requestFieldMapping: RequestFieldMapping?,
/**
* Только для [TYPE_REQUEST_TRIGGER]
* параметры запроса на триггер
*/
val demandRequest: DemandDynamicRequest?
) {
/**
* All variations of [dataTypeId] with their regex:
*/
companion object {
const val TYPE_STATIC_TITLE = 1//.*
const val TYPE_STATIC_DESCRIPTION = 2//.*
const val TYPE_HIDDEN_FIELD = 3//.*
const val TYPE_INPUT_TEXT = 4//.*
const val TYPE_INPUT_NUMBER = 5//^[0-9]*$
const val TYPE_INPUT_EMAIL = 6//^[A-Za-z0-9+_.-]+@(.+)$
const val TYPE_INPUT_MULTILINE = 7//.*
const val TYPE_DATE = 8//^\d{4}\-(0?[1-9]|1[012])\-(0?[1-9]|[12][0-9]|3[01])$
const val TYPE_SELECT = 9//^[0-9]*$
const val TYPE_MULTISELECT = 10//^[0-9]*$
const val TYPE_FLAG = 11//^[0-1]$
const val TYPE_FORMULA = 12//.*
const val TYPE_STATIC_AUTOFILL = 13//.*
const val TYPE_SWITCHER = 14//.*
const val TYPE_CARD = 15//.*
const val TYPE_RADIO = 16//.*
const val TYPE_INPUT_SUM = 17//^[0-9.]*$
const val TYPE_STATIC_DEPENDENT = 18//.*
const val TYPE_INPUT_FILE = 19//.* - загрузка файла
const val TYPE_STATIC_DECIMAL_FIELD = 20//^\d+\.?\d{0,2}$ - статичное числовое поле с разделителями
const val TYPE_REQUEST_TRIGGER = 21//.*
const val TYPE_AUTOCOMPLETE = 22//.*
const val TYPE_SIMPLE_SELECT = 23//.*
const val TYPE_LINK = 26//.*
}
}
/**
* Описание ограничений для значения поля
*
* есть два типа валидации в зависимости от [valueType]:
* 1) Простая валидация [Constraint.VALUE_TYPE_ABSOLUTE]. Валидируем со значением из [Constraint.value].
* Пример: Значение поля не может быть больше max значения
* 2) Сложная валидация [Constraint.VALUE_TYPE_RELATIVE]. Валидируем со значением с другого поля.
* Пример: Значение поля не может быть больше, чем значения другого поля
*/
@Keep
data class Constraint(
val id: Long?,
val constraintId: Long?,
val fieldId: Long?,
val demandFieldId: Long?,
/**
* Смотри список всех кодов в компаньоне
*/
val code: String?,
val errorMessage: String?,
@SerializedName("localeValueMap")
val translatedErrorMessage: Translation,
val translationKey: String?,
val value: String?,
val valueType: String?
) {
companion object {
/**
* Абсолютное значение. Значение, с которым нужно будет сравнить пишется менеджером.
* Какое-то конкретное число или дата
* одно из двух значений [valueType]
*/
const val VALUE_TYPE_ABSOLUTE = "ABSOLUTE"
/**
* Значение, с которым нужно будет сравнить берется из другого поля заявления.
* Тогда значением [value] констрейнта будет id поля заявления.
* одно из двух значений [valueType]
*/
const val VALUE_TYPE_RELATIVE = "RELATIVE"
/**
* Ограничения для числовых полей (поле [code])
* [CONSTRAINT_CODE_MULTIPLICITY] - Сумма должна быть кратна [value]
* [CONSTRAINT_CODE_MIN] - минимальное значение - [value]
* [CONSTRAINT_CODE_MAX] - максимальное значение - [value]
*/
const val CONSTRAINT_CODE_MULTIPLICITY = "multiplicity"
const val CONSTRAINT_CODE_MIN = "min"
const val CONSTRAINT_CODE_MAX = "max"
/**
* Ограничение для текстовых полей (поле [code])
* Содержит regex-маску в поле [value]
* Проверяет соответствие этой маске
*/
const val CONSTRAINT_CODE_PATTERN = "pattern"
/**
* Ограничения для поля Дата (поле [code])
* [CONSTRAINT_CODE_MIN_DATE] - не раньше даты [value]
* [CONSTRAINT_CODE_MAX_DATE] - не позже даты [value]
* [CONSTRAINT_CODE_BEFORE_TODAY] - не позже текущей даты
* [CONSTRAINT_CODE_AFTER_TODAY] - не раньше текущей даты
*/
const val CONSTRAINT_CODE_MIN_DATE = "min_date"
const val CONSTRAINT_CODE_MAX_DATE = "max_date"
const val CONSTRAINT_CODE_BEFORE_TODAY = "is_before_today"
const val CONSTRAINT_CODE_AFTER_TODAY = "is_after_today"
}
}
/**
* Только для [DemandTypeField.TYPE_REQUEST_TRIGGER]
*
* на каждое поле, указанное в [requestFieldList] вешается этот триггер,
* он будет делать запрос на [endpoint] и из ответа заполнять поля из [responseFieldList].
* При этом все значения полей из [requestFieldList] идут в запрос в виде query-параметров,
* даже если они пустые
*/
@Keep
data class DemandDynamicRequest(
val code: String?,
val name: String?,
val endpoint: String?,
val requestFieldList: List<TriggerField>?,
val responseFieldList: List<TriggerField>?
)
/**
* Только для [DemandTypeField.TYPE_REQUEST_TRIGGER]
* обозначает поля, на которые вешается триггер запроса, если это [DemandDynamicRequest.requestFieldList]
* обозначает поля, которые заполняются ответом на запрос, если это [DemandDynamicRequest.responseFieldList]
* [id] - айди поля (маппится через [RequestFieldMapping])
* [name] - query-параметр для запроса [DemandDynamicRequest.endpoint] или имя json-параметра ответа
*/
@Keep
data class TriggerField(
val id: Long?,
val name: String?
)
/**
* Только для [DemandTypeField.TYPE_REQUEST_TRIGGER]
* Маппинг полей [DemandTypeField.id] с [TriggerField.id] для [DemandDynamicRequest]
* keys = [TriggerField.id] as String
* values = [DemandTypeField.id]
*/
@Keep
data class RequestFieldMapping(
val requestFieldMap: Map<String, Long>?,
val responseFieldMap: Map<String, Long>?
)
/**
* Только для [DemandTypeField.TYPE_SWITCHER]
*
* Управляет видимостью полей
* Если выполняются все условия в [conditions]
* то показать поле с id = [fieldId]
*/
@Keep
data class SwitcherInstruction(
val conditions: List<SwitcherCondition>,
val fieldId: Long
)
/**
* Только для [DemandTypeField.TYPE_SWITCHER]
*
* Описание условия показа поля
* В основном, это значение [DemandTypeField.value] ("true"-"false" для переключателей) в виде String
* Но для числовых полей может прийти Map-объект, где будут указаны числовые условия:
* gte -> ">="
* gt -> ">"
* lte -> "<="
* lt -> "<"
* eq -> "=="
* neq -> "!="
* todo мб лучше написать кастомный десериализатор, чем вручную парсить Map
*/
@Keep
data class SwitcherCondition(
val sourceFieldId: Long,
/**
* Может быть String, Object
*/
val value: Any?
)
/**
* Только для [DemandTypeField.TYPE_FORMULA]
*
* Рекурсивное выражение для формулы
* означает, что данное поле считается относительно
* других полей [operand] по формуле
*/
@Keep
data class FormulaExpression(
val bracketsOnFront: Int,
/**
* [DemandTypeField.code] поля
*/
val operand: String,
val percentaged: Boolean,
val bracketsOnBack: Int,
/**
* - минус
* ▾ конец выражения
*/
val operator: String,
val expression: FormulaExpression?
)
@Keep
data class AttachedFile(
val id: Long,
val sourceId: Long?,
val fileserverModuleId: Long?,
val filename: String?,
val contentType: String?,
val path: String?,
val customerId: Long?,
val managerId: Long?,
val languageCode: Any?,
val fileserverModuleDTO: Any?,
val name: String?
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment