import BaseService from './BaseService.js'; import FalukantPredefineFirstname from '../models/falukant/predefine/firstname.js'; import FalukantPredefineLastname from '../models/falukant/predefine/lastname.js'; import FalukantUser from '../models/falukant/data/user.js'; import User from '../models/community/user.js'; import FalukantCharacter from '../models/falukant/data/character.js'; import RegionData from '../models/falukant/data/region.js'; import RegionType from '../models/falukant/type/region.js'; import { Sequelize } from 'sequelize'; import FalukantStock from '../models/falukant/data/stock.js'; import FalukantStockType from '../models/falukant/type/stock.js'; import { notifyUser } from '../utils/socket.js'; import { differenceInDays } from 'date-fns'; import TitleOfNobility from '../models/falukant/type/title_of_nobility.js'; import Branch from '../models/falukant/data/branch.js'; import BranchType from '../models/falukant/type/branch.js'; class FalukantService extends BaseService { async getFalukantUserByHashedId(hashedId) { const falukantUser = await FalukantUser.findOne({ include: [{ model: User, as: 'user', attributes: ['username', 'hashedId'], where: { hashedId: hashedId }, } ], }); return falukantUser; } async getUser(hashedUserId) { const falukantUser = await FalukantUser.findOne({ include: [{ model: User, as: 'user', attributes: ['username', 'hashedId'], where: { hashedId: hashedUserId }, }, { model: FalukantCharacter, as: 'character', include: [ { model: FalukantPredefineFirstname, as: 'definedFirstName', attributes: ['name'] }, { model: FalukantPredefineLastname, as: 'definedLastName', attributes: ['name'] }, { model: TitleOfNobility, as: 'nobleTitle', attributes: ['labelTr'] } ], attributes: ['birthdate', 'gender'], }, { model: RegionData, as: 'mainBranchRegion', include: [ { model: RegionType, as: 'regionType', } ], attributes: ['name'], }, { model: Branch, as: 'branches', include: [ { model: BranchType, as: 'branchType', attributes: ['labelTr'] }, { model: RegionData, as: 'region', include: [ { model: RegionType, as: 'regionType', } ], attributes: ['name'], } ] } ], attributes: ['money', 'creditAmount', 'todayCreditTaken'], }); if (!falukantUser) { throw new Error('User not found'); } const character = falukantUser.character; if (character && character.birthdate) { const birthdate = new Date(character.birthdate); birthdate.setHours(0); birthdate.setMinutes(0); const currentDate = new Date(); currentDate.setHours(0); currentDate.setMinutes(0); const ageInDays = differenceInDays(currentDate, birthdate); character.setDataValue('age', ageInDays); } return falukantUser; } async randomFirstName(gender) { const names = await FalukantPredefineFirstname.findAll({ where: { gender: gender } }); return names[Math.floor(Math.random() * names.length)].name; } async randomLastName() { const names = await FalukantPredefineLastname.findAll(); return names[Math.floor(Math.random() * names.length)].name; } async createUser(hashedUserId, gender, firstName, lastName) { try { const user = await this.getUserByHashedId(hashedUserId); const userExistsCheck = await FalukantUser.findOne({ where: { userId: user.id } }); if (userExistsCheck) { throw new Error('User already exists in Falukant.'); } let firstNameObject = await FalukantPredefineFirstname.findOne({ where: { name: firstName } }); let lastNameObject = await FalukantPredefineLastname.findOne({ where: { name: lastName } }); if (!firstNameObject) { firstNameObject = await FalukantPredefineFirstname.create({ name: firstName, gender: gender }); } if (!lastNameObject) { lastNameObject = await FalukantPredefineLastname.create({ name: lastName }); } const randomRegion = await RegionData.findOne({ order: Sequelize.fn('RANDOM'), limit: 1, include: [ { model: RegionType, as: 'regionType', where: { labelTr: 'city' } } ] }); if (!randomRegion) { throw new Error('No region found with the label "city".'); } const titleOfNobility = await TitleOfNobility.findOne({ where: { labelTr: 'noncivil' } }); if (!titleOfNobility) { throw new Error('No title of nobility found with the label "noncivil".'); } const falukantUser = await FalukantUser.create({ userId: user.id, money: 50.00, creditAmount: 0.00, todayCreditTaken: 0.00, creditInterestRate: 0.00, mainBranchRegionId: randomRegion.id, }); const fourteenDaysAgo = new Date(); fourteenDaysAgo.setDate(fourteenDaysAgo.getDate() - 14); const character = await FalukantCharacter.create({ userId: falukantUser.id, regionId: randomRegion.id, firstName: firstNameObject.id, lastName: lastNameObject.id, gender: gender, birthdate: fourteenDaysAgo, titleOfNobility: titleOfNobility.id, }); await FalukantStock.create({ userId: falukantUser.id, regionId: randomRegion.id, stockTypeId: (await FalukantStockType.findOne({ where: [{ label_tr: 'wood' }] })).id, quantity: 10, }); falukantUser['character'] = character; const branchType = await BranchType.findOne({ where: { labelTr: 'fullstack' } }); await Branch.create({ userId: falukantUser.id, regionId: randomRegion.id, branchTypeId: branchType.id, }) notifyUser(user.hashedId, 'reloadmenu', {}); return falukantUser; } catch (error) { console.error('Error creating character'); console.log(error); } } async getInfo(hashedUserId) { try { const user = await User.findOne({ where: { hashedId: hashedUserId } }); if (!user) { throw new Error('User not found'); } const falukantUser = await FalukantUser.findOne({ include: [{ model: User, as: 'user', attributes: ['hashedId'], where: { hashedId: hashedUserId }, }, { model: FalukantCharacter, as: 'character', attributes: ['birthdate', 'health'], }, ], attributes: ['money'] }); if (!falukantUser) { throw new Error('User not found'); } const character = falukantUser.character; if (character && character.birthdate) { const birthdate = new Date(character.birthdate); birthdate.setHours(0); birthdate.setMinutes(0); const currentDate = new Date(); currentDate.setHours(0); currentDate.setMinutes(0); const ageInDays = differenceInDays(currentDate, birthdate); character.setDataValue('age', ageInDays); } return falukantUser; } catch (error) { console.error('Error getting character info'); console.log(error); } } async getBranches(hashedUserId) { try { const falukantUser = await this.getFalukantUserByHashedId(hashedUserId); if (!falukantUser) { throw new Error('User not found'); } const branches = await Branch.findAll({ where: { falukantUserId: falukantUser.id }, include: [ { model: BranchType, as: 'branchType', attributes: ['labelTr'], }, { model: RegionData, as: 'region', attributes: ['name'], } ], attributes: ['id', 'regionId'], order: [['branchTypeId', 'ASC']], }); const enrichedBranches = branches.map(branch => ({ ...branch.toJSON(), isMainBranch: falukantUser.mainBranchRegionId === branch.regionId, })); return enrichedBranches; } catch (error) { console.error('Error in getBranches:', error); throw new Error('Failed to retrieve branches'); } } } export default new FalukantService();