budget-go/frontend/js/models/category.js
2025-03-31 16:44:01 +02:00

193 lines
4.4 KiB
JavaScript

import { requestCallback, request } from '../lib/request'
import { renderCategory, renderEuro, renderLabelWithSum } from '../lib/renderers'
const endpoints = {
list: '/api/category',
item: '/api/category',
}
const getList = async (query, callback) => {
return requestCallback(`${endpoints.list}?${new URLSearchParams(query)}`, {}, callback ?? (() => true))
}
const getOne = async (query, callback) => {
return request(`${endpoints.list}?${new URLSearchParams(query)}`, {})
.then((data) => data.rows[0] ?? null)
.then(callback ?? (() => true))
}
const write = async (endpoint, data, callback, callbackError) => {
return requestCallback(
endpoint,
{
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(fixData(data)),
},
callback ?? (() => true),
).catch(callbackError ?? (() => true))
}
const create = async (data, callback, callbackError) => {
return write(`${endpoints.item}`, data, callback, callbackError)
}
const update = async (data, callback, callbackError) => {
return write(`${endpoints.item}/${data.id}`, data, callback, callbackError)
}
const fixData = (data) => {
if (data.month_threshold !== null && data.month_threshold !== '') {
data.month_threshold = parseFloat(data.month_threshold)
} else {
data.month_threshold = null
}
if (data.rules === null) {
data.rules = []
}
data.rules.forEach((value, key) => {
if (value.amount !== null && value.amount !== '') {
data.rules[key].amount = parseFloat(value.amount)
}
if (value.date_from) {
data.rules[key].date_from = toISODateString(value.date_from, 0, 0, 0)
}
if (value.date_to) {
data.rules[key].date_to = toISODateString(value.date_to, 23, 59, 59)
}
for (let i in value) {
if (value[i] === '') {
data.rules[key][i] = null
}
}
})
data.ignore_transactions = data.ignore_transactions === 1
return data
}
const remove = async (id, callback, callbackError) => {
return requestCallback(
`${endpoints.item}/${id}`,
{
method: 'DELETE',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
},
callback ?? (() => true),
).catch(callbackError ?? (() => true))
}
const createForm = (item) => {
if (!item) {
item = {
id: null,
label: null,
color: '#9eb1e7',
rules: [],
month_threshold: null,
ignore_transactions: 0,
}
}
const data = { ...item }
if (data.rules) {
data.rules.forEach((value, key) => {
if (value.date_from) {
data.rules[key].date_from = fromISODateString(value.date_from)
}
if (value.date_to) {
data.rules[key].date_to = fromISODateString(value.date_to)
}
})
}
data.ignore_transactions = data.ignore_transactions ? 1 : 0
return {
data: data,
error: null,
fields: [
{
label: 'Libellé',
type: 'text',
required: true,
key: 'label',
},
{
label: 'Seuil mensuel',
type: 'number',
required: false,
key: 'month_threshold',
},
{
label: 'Ignorer les transactions liées',
widget: 'select',
required: false,
options: [
{ value: 0, text: 'Non' },
{ value: 1, text: 'Oui' },
],
key: 'ignore_transactions',
},
{
label: 'Couleur',
type: 'color',
required: true,
key: 'color',
},
{
label: null,
widget: 'rules',
required: true,
key: 'rules',
},
],
}
}
const getListFields = () => {
return [
{
key: 'label',
label: 'Libellé',
render: (item) => renderCategory(item),
},
{
key: 'month_threshold',
renderLabel: (rows) => renderLabelWithSum('Seuil mensuel', rows, 'month_threshold'),
width: '150px',
thClasses: ['text-end'],
tdClasses: ['text-end'],
render: (item) => renderEuro(item.month_threshold),
},
]
}
const toISODateString = (v, h, m, s) => {
const d = new Date(v)
d.setUTCHours(h)
d.setUTCMinutes(m)
d.setUTCSeconds(s)
return d.toISOString()
}
const fromISODateString = (v) => {
return v.split('T', 1)[0]
}
export { endpoints, getList, getOne, create, update, remove, getListFields, createForm }