mirror of
https://github.com/cupcakearmy/obolus.git
synced 2025-09-06 08:10:39 +00:00
backend
This commit is contained in:
68
api/src/entities/purchase.ts
Normal file
68
api/src/entities/purchase.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import { BaseEntity, Column, Entity, JoinTable, ManyToMany, ManyToOne, PrimaryColumn } from 'typeorm'
|
||||
import UUID from 'uuid/v4'
|
||||
|
||||
import User from './user'
|
||||
|
||||
@Entity()
|
||||
export default class Purchase extends BaseEntity {
|
||||
|
||||
@PrimaryColumn()
|
||||
id!: string
|
||||
|
||||
@Column('real')
|
||||
price: number
|
||||
|
||||
@Column()
|
||||
description: string
|
||||
|
||||
@Column()
|
||||
when: number
|
||||
|
||||
@Column('blob', { nullable: true })
|
||||
photo?: string
|
||||
|
||||
@ManyToOne(type => User, user => user.purchases, { eager: true })
|
||||
payer: User
|
||||
|
||||
@ManyToMany(type => User, user => user.debts, { eager: true })
|
||||
@JoinTable()
|
||||
debtors: User[]
|
||||
|
||||
constructor(price: number, payer: User, debtors: User[], description = '') {
|
||||
super()
|
||||
|
||||
this.id = UUID()
|
||||
this.price = price
|
||||
this.payer = payer
|
||||
this.debtors = debtors
|
||||
this.description = description
|
||||
this.when = Date.now()
|
||||
}
|
||||
|
||||
static async getCurrentStats() {
|
||||
|
||||
// @ts-ignore
|
||||
const users: { [user: string]: number } = Object.fromEntries((await User.find()).map(user => [user.name, 0]))
|
||||
const all: Purchase[] = await Purchase.find()
|
||||
|
||||
for (const { price, debtors, payer, description } of all) {
|
||||
const each: number = price / debtors.length
|
||||
|
||||
for (const debtor of debtors)
|
||||
users[debtor.name] -= each
|
||||
|
||||
users[payer.name] += price
|
||||
}
|
||||
|
||||
// Sum of all the calculations, should be 0.
|
||||
const _error = Object.values(users).reduce((acc, cur) => acc + cur, 0)
|
||||
|
||||
// @ts-ignore
|
||||
const approximated = Object.fromEntries(Object.entries(users).map(([name, value]) => [name, Number(value.toFixed(2))]))
|
||||
|
||||
return {
|
||||
_error,
|
||||
...approximated,
|
||||
}
|
||||
}
|
||||
}
|
44
api/src/entities/user.ts
Normal file
44
api/src/entities/user.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { BaseEntity, Column, Entity, ManyToMany, OneToMany, PrimaryColumn } from 'typeorm'
|
||||
import UUID from 'uuid/v4'
|
||||
import Purchase from './purchase'
|
||||
|
||||
@Entity()
|
||||
export default class User extends BaseEntity {
|
||||
|
||||
@PrimaryColumn()
|
||||
id!: string
|
||||
|
||||
@Column({ unique: true })
|
||||
name: string
|
||||
|
||||
@Column({nullable: true})
|
||||
avatar?: string
|
||||
|
||||
@OneToMany(type => Purchase, purchase => purchase.payer)
|
||||
purchases!: Purchase[]
|
||||
|
||||
@ManyToMany(type => Purchase, purchase => purchase.debtors)
|
||||
debts!: Purchase[]
|
||||
|
||||
constructor(name: string) {
|
||||
super()
|
||||
|
||||
this.id = UUID()
|
||||
this.name = name
|
||||
}
|
||||
|
||||
static async createOrGet(name: string): Promise<User> {
|
||||
const existent = await User.findOne({ where: { name } })
|
||||
return existent
|
||||
? existent
|
||||
: await new User(name).save()
|
||||
}
|
||||
|
||||
static getFromName(name: string, withRelations: boolean = false): Promise<User> {
|
||||
return User.findOneOrFail({
|
||||
where: { name },
|
||||
relations: withRelations ? ['debts', 'purchases'] : undefined,
|
||||
})
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user