Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vil 144 #977

Merged
merged 108 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
ef8c8f0
add folder expression and file index.tsx
guillaume-pages Nov 21, 2023
208103f
for stash
guillaume-pages Nov 21, 2023
cea85c9
add new type
guillaume-pages Nov 23, 2023
cf00f50
add a file game config in a new folder config for standardization
Nov 29, 2023
cdb7562
Merge branch 'game_expression' of https://github.com/parlemonde/1vill…
guillaume-pages Dec 5, 2023
ebccc22
standardisation
guillaume-pages Dec 7, 2023
e4e6795
modif config game
guillaume-pages Dec 12, 2023
021ab54
New feature game expression and money : add a context for all game, r…
guillaume-pages Dec 28, 2023
264949b
Fix some lint
guillaume-pages Dec 28, 2023
3b67f35
Fix typescript error
guillaume-pages Dec 29, 2023
bb0882e
Feature : hidden input when userSelection is === Français
guillaume-pages Dec 29, 2023
d4a4d16
add a variable gameResponse in gameContext and remove some import not…
guillaume-pages Jan 3, 2024
ee6e0dc
fix eslint & ts
guillaume-pages Jan 3, 2024
37d4687
Merge branch 'game_expression' of https://github.com/parlemonde/1vill…
nathan7594 Jan 3, 2024
cf4b742
save of all information during the user create the game
guillaume-pages Jan 5, 2024
cb56e0b
forgot to remove a console.log
guillaume-pages Jan 5, 2024
e2d9190
modif de style
guillaume-pages Jan 8, 2024
8c12255
Ajout du jeux monnaie fonctionnelle
nathan7594 Jan 8, 2024
747c573
Merge branch 'game_monnaie' of https://github.com/parlemonde/1village…
guillaume-pages Jan 8, 2024
152a640
Merge branch 'game_expression' of https://github.com/parlemonde/1vill…
nathan7594 Jan 8, 2024
2958e6f
Changement deux trois truc
nathan7594 Jan 9, 2024
7144e82
Merge branch 'master' of https://github.com/parlemonde/1village into …
guillaume-pages Jan 9, 2024
2ba5f30
Standardization of components, creation of a variable which copies th…
guillaume-pages Jan 16, 2024
61a641e
reworked folder monnaie
guillaume-pages Jan 16, 2024
c29a3fc
add a null possibility on gameType in file activitychoice/index.tsx
guillaume-pages Jan 16, 2024
ae554fe
Displaying the input.selectedValue when they have been populated
guillaume-pages Jan 17, 2024
f8fc952
add component GameMedia
guillaume-pages Jan 23, 2024
0b3a5ed
display component image ok
guillaume-pages Jan 24, 2024
61b9f08
component media video ok
guillaume-pages Jan 24, 2024
4e27c73
Push ajout de fonctionnalité
nathan7594 Jan 25, 2024
9c2af23
Merge branch 'game_expression' of https://github.com/parlemonde/1vill…
nathan7594 Jan 25, 2024
fb340d8
add a check on values for display button publish.
guillaume-pages Feb 1, 2024
4375673
Finish previsualisation expression monney
nathan7594 Feb 5, 2024
d45721c
Merge branch 'game_expression' of https://github.com/parlemonde/1vill…
nathan7594 Feb 5, 2024
e8b3ce3
Merge resolving conflit with game_expression
nathan7594 Feb 5, 2024
be981c4
new card activity GameCard
guillaume-pages Feb 6, 2024
c1fda6a
Merge branch 'game_monnaie' of https://github.com/parlemonde/1village…
guillaume-pages Feb 6, 2024
1f77209
request backend game
guillaume-pages Feb 8, 2024
522863c
add a route API
guillaume-pages Feb 21, 2024
79bde08
function create a game and get all games
guillaume-pages Feb 21, 2024
aafdfe9
Debug Jira
nathan7594 Feb 22, 2024
7ae8c6e
add 3 others routes API
guillaume-pages Feb 22, 2024
27a22f9
Pull origin game_expression into game_expression
Feb 27, 2024
430eb0d
modif eslint
guillaume-pages Feb 27, 2024
b276706
Pull branch 'game_monnaie' into game_expression
guillaume-pages Feb 27, 2024
52bee2f
Debut Previsualisation
nathan7594 Feb 27, 2024
662beab
Merge branch 'game_expression' of https://github.com/parlemonde/1vill…
nathan7594 Feb 27, 2024
dd16a25
GameCard display ok, 7 request ok, 2 remain to be done
guillaume-pages Feb 28, 2024
0e5d997
modif request for accept a param subType
guillaume-pages Feb 28, 2024
b5ae7f3
modif type of data in gameController games/standardGame
guillaume-pages Feb 28, 2024
b26f09c
changement du chemin de src/config/games/game en ../src/config/games/…
guillaume-pages Feb 28, 2024
20e7fff
changement
guillaume-pages Feb 28, 2024
31a3edb
Début visualisation
nathan7594 Feb 28, 2024
28f6a4d
Push push de la branche monnaie
nathan7594 Mar 4, 2024
dabcbe4
Push taff avec robin
nathan7594 Mar 4, 2024
5f37e92
Merge branch 'game_monnaie' of https://github.com/parlemonde/1village…
nathan7594 Mar 4, 2024
41b2710
Avancement refacto + standardisation visualisation
nathan7594 Mar 4, 2024
7a755a5
new card
guillaume-pages Mar 4, 2024
e8eceab
Push dans le push
nathan7594 Mar 4, 2024
d872251
Merge branch 'game_expression' of https://github.com/parlemonde/1vill…
nathan7594 Mar 4, 2024
1afccd3
Creation composant get all
nathan7594 Mar 5, 2024
74c48db
Push des card + route par id
nathan7594 Mar 5, 2024
3dde1a8
remove game from Mes activités publiées to Mes jeux
guillaume-pages Mar 6, 2024
bc146c5
Merge branch 'game_monnaie' into VIL-144
guillaume-pages Mar 6, 2024
1368aae
remove button Jouer, display 6 cards, when more a scroll bar is display
guillaume-pages Mar 6, 2024
11137c3
Push for pull
nathan7594 Mar 6, 2024
9ae9ab2
Merge branch 'game_monnaie' of https://github.com/parlemonde/1village…
nathan7594 Mar 6, 2024
1cdfa5f
Merge branch 'VIL-144' of https://github.com/parlemonde/1village into…
nathan7594 Mar 6, 2024
980462c
display card ok in page ma-classe. Todo : change mimic to work with t…
guillaume-pages Mar 6, 2024
a6114c9
starting to pass mimique game on same structure as expression and monney
guillaume-pages Mar 7, 2024
fa167eb
Ajout display jeux + route redirection
nathan7594 Mar 8, 2024
9dac854
merge game_monnaie into VIL-144
guillaume-pages Mar 11, 2024
65981bf
clean eslint
guillaume-pages Mar 11, 2024
15efa71
test change game to games
guillaume-pages Mar 11, 2024
f6bb458
Push modification
nathan7594 Mar 11, 2024
0c5864d
Merge branch 'VIL-144' of https://github.com/parlemonde/1village into…
nathan7594 Mar 11, 2024
427d35c
refacto eslint
guillaume-pages Mar 11, 2024
a7a31b4
Repush
nathan7594 Mar 11, 2024
71c17b3
Merge branch 'VIL-144' of https://github.com/parlemonde/1village into…
nathan7594 Mar 11, 2024
5a9e2cb
fixing some css
guillaume-pages Mar 12, 2024
9f9ac53
Merge branch 'VIL-144' of https://github.com/parlemonde/1village into…
nathan7594 Mar 12, 2024
d5ed495
Fix Jouer avec Robin 12/03
nathan7594 Mar 12, 2024
567b655
Ready for staging
guillaume-pages Mar 13, 2024
46a4b53
fix lint
guillaume-pages Mar 13, 2024
19f9777
fix retour de bug ticket VIL-144
guillaume-pages Mar 14, 2024
f745d1d
add a button back to displayList when you're in page play
guillaume-pages Mar 14, 2024
c230f7b
migration ok for staging
guillaume-pages Mar 18, 2024
dbce86f
eslint
guillaume-pages Mar 18, 2024
da7e5ab
debug with Mel
guillaume-pages Mar 18, 2024
732bfd6
Mooving all declaration type from game config to type game
guillaume-pages Mar 18, 2024
b4c9126
oublie un import
guillaume-pages Mar 18, 2024
1d4e441
fix display video in DisplayList
guillaume-pages Mar 18, 2024
64a1bc9
repush
guillaume-pages Mar 18, 2024
b6492bf
repush2
guillaume-pages Mar 18, 2024
f931978
admin can play
guillaume-pages Mar 19, 2024
681d8dc
remove old mimic game
guillaume-pages Mar 19, 2024
41eadc9
correction route
guillaume-pages Mar 19, 2024
035eedf
fix display bug
guillaume-pages Mar 19, 2024
0dbcb90
fix ticket VIL-144
guillaume-pages Mar 20, 2024
6917255
merge master into VIL-144
guillaume-pages Mar 25, 2024
bab043a
create user
nathan7594 Sep 2, 2024
2d452da
Merge branch 'master' into VIL-144
nathan7594 Sep 2, 2024
a6d98cc
Push pour staging
nathan7594 Sep 2, 2024
52993f8
Merge branch 'VIL-144' of https://github.com/parlemonde/1village into…
nathan7594 Sep 2, 2024
721fff4
Push for merge game in staging
nathan7594 Sep 2, 2024
fd19186
Push
nathan7594 Sep 2, 2024
180d500
Test
nathan7594 Sep 2, 2024
fa33883
hotfix VIL-567 - modif UI bouton et affichage date
guillaume-pages Sep 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
Binary file not shown.
Binary file added .yarn/cache/fsevents-patch-6b67494872-10.zip
Binary file not shown.
Binary file added .yarn/cache/fsevents-patch-afc6995412-10.zip
Binary file not shown.
36 changes: 18 additions & 18 deletions server/controllers/activity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,24 @@ activityController.put({ path: '/:id', userType: UserType.TEACHER }, async (req:
res.sendJSON(activity);
});

// --- create a game ---
const createGame = async (data: GameData, activity: Activity): Promise<Game> => {
const id = data.gameId;
const game = id ? await AppDataSource.getRepository(Game).findOneOrFail({ where: { id: data.gameId || 0 } }) : new Game();
delete data['gameId'];
game.activityId = activity.id;
game.villageId = activity.villageId;
game.userId = activity.userId;
game.type = activity.subType;
game.signification = data.signification;
game.fakeSignification1 = data.fakeSignification1;
game.fakeSignification2 = data.fakeSignification2;
game.origine = data.origine;
game.video = data.video;
await AppDataSource.getRepository(Game).save(game);
return game;
};

activityController.put({ path: '/:id/askSame', userType: UserType.TEACHER }, async (req: Request, res: Response, next: NextFunction) => {
const user = req.user;
if (!user) {
Expand Down Expand Up @@ -404,24 +422,6 @@ activityController.put({ path: '/:id/askSame', userType: UserType.TEACHER }, asy
res.sendJSON(activity);
});

// --- create a game ---
const createGame = async (data: GameData, activity: Activity): Promise<Game> => {
const id = data.gameId;
const game = id ? await AppDataSource.getRepository(Game).findOneOrFail({ where: { id: data.gameId || 0 } }) : new Game();
delete data['gameId'];
game.activityId = activity.id;
game.villageId = activity.villageId;
game.userId = activity.userId;
game.type = activity.subType;
game.signification = data.signification;
game.fakeSignification1 = data.fakeSignification1;
game.fakeSignification2 = data.fakeSignification2;
game.origine = data.origine;
game.video = data.video;
await AppDataSource.getRepository(Game).save(game);
return game;
};

// --- create a image ---
const createStory = async (data: StoryElement, activity: Activity, type: ImageType, inspiredStoryId: number = 0): Promise<Image> => {
const id = data.imageId;
Expand Down
273 changes: 242 additions & 31 deletions server/controllers/game.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import type { JSONSchemaType } from 'ajv';
import type { NextFunction, Request, Response } from 'express';

import type { ActivityContent, AnyData } from '../../types/activity.type';
import { ActivityStatus } from '../../types/activity.type';
import { Activity } from '../entities/activity';
import { Game } from '../entities/game';
import { GameResponse } from '../entities/gameResponse';
import { UserType } from '../entities/user';
Expand Down Expand Up @@ -156,29 +159,31 @@ gameController.get({ path: '/ableToPlay', userType: UserType.TEACHER }, async (r
next();
return;
}
const games = await AppDataSource.getRepository(Game)
.createQueryBuilder('game')
.leftJoinAndSelect('game.responses', 'responses')
.andWhere('`game`.`villageId` = :villageId', { villageId: villageId })
.andWhere('`game`.`type` = :type', { type: type })
.andWhere(
(qb) => {
const subQuery = qb
.subQuery()
.select()
.from(GameResponse, 'response')
.where(`response.userId = :userId`, { userId: userId })
.andWhere(`response.gameId = game.id`)
.andWhere(`response.isOldResponse = 0`)
.getQuery();
return 'NOT EXISTS ' + subQuery;
},
{ userId: req.user.id },
)
.getMany();
res.sendJSON({
games: games,
});
if (type === 0) {
const games = await AppDataSource.getRepository(Game)
.createQueryBuilder('game')
.leftJoinAndSelect('game.responses', 'responses')
.andWhere('`game`.`villageId` = :villageId', { villageId: villageId })
.andWhere('`game`.`type` = :type', { type: type })
.andWhere(
(qb) => {
const subQuery = qb
.subQuery()
.select()
.from(GameResponse, 'response')
.where(`response.userId = :userId`, { userId: userId })
.andWhere(`response.gameId = game.id`)
.andWhere(`response.isOldResponse = 0`)
.getQuery();
return 'NOT EXISTS ' + subQuery;
},
{ userId: req.user.id },
)
.getMany();
res.sendJSON({
games: games,
});
}
});

//--- retrieve answers to the mimic with this id ---
Expand All @@ -201,6 +206,7 @@ gameController.get({ path: '/stats/:gameId', userType: UserType.TEACHER }, async

type UpdateActivity = {
value: string;
villageId: number;
};

const ANSWER_M_SCHEMA: JSONSchemaType<UpdateActivity> = {
Expand All @@ -209,9 +215,12 @@ const ANSWER_M_SCHEMA: JSONSchemaType<UpdateActivity> = {
value: {
type: 'string',
},
villageId: {
type: 'number',
},
},
required: [],
additionalProperties: false,
additionalProperties: true,
};

const answerGameValidator = ajv.compile(ANSWER_M_SCHEMA);
Expand Down Expand Up @@ -245,11 +254,6 @@ gameController.put({ path: '/play/:id', userType: UserType.TEACHER }, async (req
return;
}

const game = await AppDataSource.getRepository(Game).findOne({ where: { id: id } });
if (!game) {
next();
return;
}
const responses = await AppDataSource.getRepository(GameResponse).find({ where: { userId: userId, id: id } });
if (responses.length > 2) {
next();
Expand All @@ -258,12 +262,219 @@ gameController.put({ path: '/play/:id', userType: UserType.TEACHER }, async (req

const gameResponse = new GameResponse();
gameResponse.value = data.value;
gameResponse.gameId = game.id;
gameResponse.villageId = game.villageId;
gameResponse.gameId = id;
gameResponse.villageId = data.villageId;
gameResponse.userId = userId;

await AppDataSource.getRepository(GameResponse).save(gameResponse);
res.sendJSON(GameResponse);
});

//--- Create a standardised game ---

gameController.post({ path: '/standardGame', userType: UserType.TEACHER }, async (req: Request, res: Response, next: NextFunction) => {
if (!req.user) {
next();
return;
}

const data = req.body;
const game1 = data.game1;
const game2 = data.game2;
const game3 = data.game3;

createGame(game1, data.userId, data.villageId, data.type, data.subType, data.selectedPhase);
createGame(game2, data.userId, data.villageId, data.type, data.subType, data.selectedPhase);
createGame(game3, data.userId, data.villageId, data.type, data.subType, data.selectedPhase);

res.sendStatus(200);
});

async function createGame(data: ActivityContent[], userId: number, villageId: number, type: number, subType: number, selectedPhase: number) {
const activity = new Activity();
activity.type = type;
activity.subType = subType;
activity.status = ActivityStatus.PUBLISHED;
// TODO: Travailler sur le type de data
activity.data = data as unknown as AnyData;
activity.phase = selectedPhase;
activity.content = data;
activity.userId = userId;
activity.villageId = villageId;
activity.responseActivityId = null;
activity.responseType = null;
activity.isPinned = false;
activity.displayAsUser = false;
activity.publishDate = new Date();

await AppDataSource.getRepository(Activity).save(activity);
}

// --- Get all games standardised by subType ---

gameController.get({ path: '/allStandardGame', userType: UserType.TEACHER }, async (req: Request, res: Response, next: NextFunction) => {
if (!req.user) {
next();
return;
}

const subType = parseInt(getQueryString(req.query.subType) || '0', 10);
const villageId = req.user.type <= UserType.TEACHER ? parseInt(getQueryString(req.query.villageId) || '0', 10) || null : req.user.villageId;

const subQueryBuilder = AppDataSource.getRepository(Activity)
.createQueryBuilder('activity')
.where('activity.villageId = :villageId', { villageId: villageId })
.andWhere('activity.type = :type', { type: 4 })
.andWhere('activity.subType = :subType', { subType: subType });

const games = await subQueryBuilder
.orderBy('activity.createDate', 'DESC')
.limit(200)
.offset(0 * 200)
.getMany();

res.sendJSON(games);
});

// --- Get one game standardised ---

gameController.get({ path: '/standardGame/:id', userType: UserType.TEACHER }, async (req: Request, res: Response, next: NextFunction) => {
if (!req.user) {
next();
return;
}
const id = parseInt(req.params.id, 10) || 0;
const game = await AppDataSource.getRepository(Activity).findOne({ where: { id } });
if (!game || (req.user.type === UserType.TEACHER && req.user.villageId !== game.villageId)) {
next();
return;
}
res.sendJSON(game);
});

// --- Get one random game standardised to play ---
gameController.get({ path: '/playStandardGame', userType: UserType.TEACHER }, async (req: Request, res: Response, next: NextFunction) => {
if (!req.user) {
next();
return;
}
const villageId = req.user.type <= UserType.TEACHER ? parseInt(getQueryString(req.query.villageId) || '0', 10) || null : req.user.villageId;
const type = 4;
const subType = parseInt(getQueryString(req.query.subType) || '0', 10);
const game = await AppDataSource.getRepository(Activity)
.createQueryBuilder('activity')
.andWhere('activity.villageId = :villageId', { villageId: villageId })
.andWhere('activity.type = :type', { type: type })
.andWhere('activity.subType = :subType', { subType: subType })
.orderBy('RAND()')
.getOne();
if (!game) {
next();
return;
}
res.sendJSON(game);
});

// --- Get the last created game standardised ---

gameController.get({ path: '/latestStandard', userType: UserType.TEACHER }, async (req: Request, res: Response, next: NextFunction) => {
if (!req.user) {
next();
return;
}
const villageId = req.user.type <= UserType.TEACHER ? parseInt(getQueryString(req.query.villageId) || '0', 10) || null : req.user.villageId;
const type = 4;
const subType = parseInt(getQueryString(req.query.subType) || '0', 10);
const latestGame = await AppDataSource.getRepository(Activity)
.createQueryBuilder('activity')
.where('activity.villageId = :villageId', { villageId: villageId })
.andWhere('activity.type = :type', { type: type })
.andWhere('activity.subType = :subType', { subType: subType })
.orderBy('activity.createDate', 'DESC')
.getOne();

if (!latestGame) {
next();
return;
}

res.sendJSON(latestGame);
});

// --- Get all games standardised available ---

gameController.get({ path: '/ableToPlayStandardGame', userType: UserType.TEACHER }, async (req: Request, res: Response, next: NextFunction) => {
if (!req.user) {
next();
return;
}
const userId = req.user.id;
const villageId = req.user.type <= UserType.TEACHER ? parseInt(getQueryString(req.query.villageId) || '0', 10) || null : req.user.villageId;
const type = 4;
const subType = parseInt(getQueryString(req.query.subType) || '0', 10);

const games = await AppDataSource.getRepository(Activity)
.createQueryBuilder('activity')
.leftJoin(GameResponse, 'GameResponse')
.andWhere('`activity`.`villageId` = :villageId', { villageId: villageId })
.andWhere('`activity`.`type` = :type', { type: type })
.andWhere('`activity`.`subType` = :subType', { subType: subType })
.andWhere(
(qb) => {
const subQuery = qb
.subQuery()
.select()
.from(GameResponse, 'response')
.where(`response.userId = :userId`, { userId: userId })
.andWhere(`response.gameId = activity.id`)
.andWhere(`response.isOldResponse = 0`)
.getQuery();
return 'NOT EXISTS ' + subQuery;
},
{ userId: req.user.id },
)
.getMany();
res.sendJSON({
activities: games,
});
});

// --- Get number of games standardised available ---

gameController.get({ path: '/countAbleToPlayStandardGame', userType: UserType.TEACHER }, async (req: Request, res: Response, next: NextFunction) => {
if (!req.user) {
next();
return;
}
const userId = req.user.id;
const villageId = req.user.type <= UserType.TEACHER ? parseInt(getQueryString(req.query.villageId) || '0', 10) || null : req.user.villageId;
const type = 4;
const subType = parseInt(getQueryString(req.query.subType) || '0', 10);

const gameCount = await AppDataSource.getRepository(Activity)
.createQueryBuilder('activity')
.leftJoin(GameResponse, 'GameResponse')
.andWhere('`activity`.`villageId` = :villageId', { villageId: villageId })
.andWhere('`activity`.`type` = :type', { type: type })
.andWhere('`activity`.`subType` = :subType', { subType: subType })
.andWhere(
(qb) => {
const subQuery = qb
.subQuery()
.select()
.from(GameResponse, 'response')
.where(`response.userId = :userId`, { userId: userId })
.andWhere(`response.gameId = activity.id`)
.andWhere(`response.isOldResponse = 0`)
.getQuery();
return 'NOT EXISTS ' + subQuery;
},
{ userId: req.user.id },
)
.getCount();
res.sendJSON({
count: gameCount,
});
});

export { gameController };
15 changes: 15 additions & 0 deletions server/migrations/1710427662589-AlterGameResponseTable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { MigrationInterface, QueryRunner } from 'typeorm';

export class AlterGameResponseTable1710427662589 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE game_response DROP FOREIGN KEY FK_3a0c737a217bbd6bbd268203fb8`);
await queryRunner.query(`ALTER TABLE game_response DROP COLUMN gameId`);
await queryRunner.query(`ALTER TABLE game_response ADD COLUMN gameId INT`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE game_response DROP COLUMN gameId`);
await queryRunner.query(`ALTER TABLE game_response ADD COLUMN gameId INT`);
await queryRunner.query(`ALTER TABLE game_response ADD CONSTRAINT FK_3a0c737a217bbd6bbd268203fb8 FOREIGN KEY (gameId) REFERENCES game(id)`);
}
}
2 changes: 1 addition & 1 deletion server/utils/iso-4217-currencies-french.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export const currencies: Currency[] = [
{ name: 'Dollars du Zimbabwe', code: 'ZWL', iso: '932' },
{ name: 'Dong', code: 'VND', iso: '704' },
{ name: 'Dram Armenien', code: 'AMD', iso: '51' },
{ name: 'Euro', code: 'EUR', iso: '978' },
{ name: 'Euros', code: 'EUR', iso: '978' },
{ name: 'Florin des Antilles néerlandaises', code: 'ANG', iso: '532' },
{ name: 'Forint', code: 'HUF', iso: '348' },
{ name: 'Franc Burundi', code: 'BIF', iso: '108' },
Expand Down
Loading
Loading