Estou tentando transformar uma lista plana de saldos de contas em uma lista de árvores de contas hierárquicas com base em uma lista de códigos exclusivos. Estou com dificuldades para resolver isso, pois não consigo ver quais etapas tomar.
Se você pensar em uma planilha do Excel, então o saldo da conta seria uma linha e o campo codes denota as colunas para quantos níveis a linha foi dividida. Isso significa efetivamente que o primeiro codes[0] é o primeiro nível e codes[1] seria o próximo e assim por diante. Ao transformar os saldos da conta em uma árvore de contas, quero somar o amountOut corretamente para cada nível (codeType e code) e então adicioná-lo como uma árvore de contas na matriz subAccounts.
Abaixo adicionei todos os tipos usados e também forneci um exemplo de entrada e saída.
interface AccountBalance {
id: string
codes: Code[]
amountOut: number
}
type Code = {
id: string
codeType: CodeTypes
code: string
description: string
}
enum CodeTypes {
account = "account",
responsible = "responsible",
project = "project",
object = "object",
counterPart = "counterPart",
free = "free",
}
type AccountTree = {
id: string
name: string
code: string
amountOut: number
subAccounts: AccountTree[]
}
Exemplo de entrada:
const accountBalances: AccountBalance[] = [
{
id: "671769fbd36fcd6c2c7f2d9b",
codes: [
{
id: "671769fbd36fcd6c2c7f2c2d",
codeType: codeTypeEnum.account,
code: "1250",
description: "Column A",
},
{
id: "671769fbd36fcd6c2c7f2bd5",
codeType: codeTypeEnum.responsible,
code: "17",
description: "Column B",
},
{
id: "671769fbd36fcd6c2c7f2bf7",
codeType: codeTypeEnum.counterPart,
code: "20",
description: "Column C",
},
],
amountOut: 24510549,
},
{
id: "671769fbd36fcd6c2c7f2d9c",
codes: [
{
id: "671769fbd36fcd6c2c7f2c2d",
codeType: codeTypeEnum.account,
code: "1250",
description: "Column A",
},
{
id: "671769fbd36fcd6c2c7f2bee",
codeType: codeTypeEnum.responsible,
code: "40",
description: "Column B",
},
{
id: "671769fbd36fcd6c2c7f2c08",
codeType: codeTypeEnum.counterPart,
code: "S3",
description: "Column C",
},
],
amountOut: 0,
},
{
id: "671769fbd36fcd6c2c7f2d9d",
codes: [
{
id: "671769fbd36fcd6c2c7f2c2d",
codeType: codeTypeEnum.account,
code: "1250",
description: "Column A",
},
{
id: "671769fbd36fcd6c2c7f2bdb",
codeType: codeTypeEnum.responsible,
code: "80",
description: "Column B",
},
{
id: "671769fbd36fcd6c2c7f2bdc",
codeType: codeTypeEnum.counterPart,
code: "52",
description: "Column C",
},
],
amountOut: 6381398,
},
]
Saída que desejo, exemplo:
const expected: AccountTree = {
id: "671769fbd36fcd6c2c7f2c2d",
name: "Column A",
code: "1250",
amountOut: 30891947,
subAccounts: [
{
id: "671769fbd36fcd6c2c7f2bd5",
name: "Column B",
code: "17",
amountOut: 24510549,
subAccounts: [
{
id: "671769fbd36fcd6c2c7f2bf7",
name: "Column C",
code: "20",
amountOut: 24510549,
subAccounts: [],
},
],
},
{
id: "671769fbd36fcd6c2c7f2bee",
name: "Column B",
code: "40",
amountOut: 0,
subAccounts: [
{
id: "671769fbd36fcd6c2c7f2c08",
name: "Column C",
code: "S3",
amountOut: 0,
subAccounts: [],
},
],
},
{
id: "671769fbd36fcd6c2c7f2bdb",
name: "Column B",
code: "80",
amountOut: 6381398,
subAccounts: [
{
id: "671769fbd36fcd6c2c7f2bdc",
name: "Column C",
code: "52",
amountOut: 6381398,
subAccounts: [],
},
],
},
],
}
O que consegui até agora é isso
const uniqueCodeTypes = [
...new Set(
accountBalances.reduce<CodeTypes[]>(
(acc, balance) => [
...acc,
...balance.codes.flatMap((code) => code.codeType),
],
[],
),
),
]
const uniqueCodesForCodeType = uniqueCodeTypes.map((codeType) => {
const uniqueCodesForCodeType = [
...new Map(
accountBalances.reduce<Code[]>((acc, balance) => {
const code = balance.codes.find(
(code) => code.codeType === codeType,
)
return code ? [...acc, code] : acc
}, []).map((code) => [code.code, code])
).values(),
]
return uniqueCodesForCodeType
})
Mas não tenho certeza de como proceder depois disso.