-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feat/add translate nomenclatures task (#1184)
Autofill missing local language fields in forms
- Loading branch information
Showing
7 changed files
with
235 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
/* eslint-env node, jest */ | ||
/* globals setup */ | ||
|
||
const formBirdsFactory = require('../../__utils__/factories/formBirdsFactory') | ||
const speciesFactory = require('../../__utils__/factories/speciesFactory') | ||
|
||
const run = (...args) => setup.api.tasks.tasks.autoTranslateNomenclatures.run(...args) | ||
|
||
beforeAll(async () => { | ||
await setup.api.models.nomenclature.create({ | ||
type: 'birds_age', | ||
labelEn: 'adult', | ||
labelBg: 'възрастен' | ||
}) | ||
|
||
await setup.api.models.nomenclature.create({ | ||
type: 'birds_behaviour', | ||
labelEn: 'singing', | ||
labelBg: 'пеене' | ||
}) | ||
|
||
await setup.api.models.nomenclature.create({ | ||
type: 'birds_behaviour', | ||
labelEn: 'feeding', | ||
labelBg: 'хранене' | ||
}) | ||
}) | ||
|
||
describe('autoTranslateNomenclatures task', () => { | ||
it('populates *Local for single choice nomenclature fields when missing', async () => { | ||
const species = await speciesFactory(setup.api) | ||
const record = await formBirdsFactory(setup.api, { | ||
species, | ||
ageEn: 'adult' | ||
}) | ||
|
||
await run({ form: 'formBirds', id: record.id }) | ||
|
||
const reloaded = await record.reload() | ||
expect(reloaded.dataValues).toEqual(expect.objectContaining({ | ||
ageLocal: 'възрастен' | ||
})) | ||
}) | ||
|
||
it('populates *Local for multiple choice nomenclature fields when missing', async () => { | ||
const species = await speciesFactory(setup.api) | ||
const record = await formBirdsFactory(setup.api, { | ||
species, | ||
behaviourEn: 'singing | feeding' | ||
}) | ||
|
||
await run({ form: 'formBirds', id: record.id }) | ||
|
||
const reloaded = await record.reload() | ||
expect(reloaded.dataValues).toEqual(expect.objectContaining({ | ||
behaviourLocal: 'пеене | хранене' | ||
})) | ||
}) | ||
|
||
it('populates *Local for multiple choice nomenclature fields with single value', async () => { | ||
const species = await speciesFactory(setup.api) | ||
const record = await formBirdsFactory(setup.api, { | ||
species, | ||
behaviourEn: 'singing' | ||
}) | ||
|
||
await run({ form: 'formBirds', id: record.id }) | ||
|
||
const reloaded = await record.reload() | ||
expect(reloaded.dataValues).toEqual(expect.objectContaining({ | ||
behaviourLocal: 'пеене' | ||
})) | ||
}) | ||
|
||
it('populates *Lang form fields when add missing translations', async () => { | ||
const species = await speciesFactory(setup.api) | ||
const record = await formBirdsFactory(setup.api, { | ||
species, | ||
ageEn: 'adult' | ||
}) | ||
|
||
await run({ form: 'formBirds', id: record.id }) | ||
|
||
const reloaded = await record.reload() | ||
expect(reloaded.dataValues).toEqual(expect.objectContaining({ | ||
ageLang: 'bg' | ||
})) | ||
}) | ||
|
||
it('Set *Local to "|" when nomenclature is not found', async () => { | ||
const species = await speciesFactory(setup.api) | ||
const record = await formBirdsFactory(setup.api, { | ||
species, | ||
ageEn: 'missing-value' | ||
}) | ||
|
||
await run({ form: 'formBirds', id: record.id }) | ||
|
||
const reloaded = await record.reload() | ||
expect(reloaded.dataValues).toEqual(expect.objectContaining({ | ||
ageLocal: '|' | ||
})) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
const { api } = require('actionhero') | ||
const sequelize = require('sequelize') | ||
const FormsTask = require('../classes/FormsTask') | ||
|
||
module.exports = class AutoTranslateNomenclatures extends FormsTask { | ||
constructor () { | ||
super() | ||
this.name = 'autoTranslateNomenclatures' | ||
this.description = 'Translate nomenclatures' | ||
// use cronjob to schedule the task | ||
// npm run enqueue autoTranslateNomenclatures | ||
this.frequency = 0 | ||
this.defaultLimit = api.config.app.translate.maxRecords | ||
} | ||
|
||
findNomenclatureFields = (form) => { | ||
return Object.entries(api.forms[form].fields).map(([key, field]) => { | ||
if (field.relation?.model === 'nomenclature') { | ||
return { | ||
key, | ||
type: field.type, | ||
nomenclature: field.relation?.filter?.type | ||
} | ||
} | ||
return null | ||
}).filter(Boolean) | ||
} | ||
|
||
filterRecords ({ force, form }) { | ||
// fore all | ||
if (force === true) return {} | ||
|
||
const nomenclatureFields = this.findNomenclatureFields(form) | ||
|
||
// no nomenclature fields | ||
if (nomenclatureFields.length === 0) { | ||
return {} | ||
} | ||
|
||
return { | ||
[sequelize.Op.or]: nomenclatureFields.map(({ key, type, nomenclature }) => { | ||
return { | ||
[sequelize.Op.and]: { | ||
[`${key}En`]: { | ||
[sequelize.Op.and]: { | ||
[sequelize.Op.not]: null, | ||
[sequelize.Op.ne]: '' | ||
} | ||
}, | ||
[`${key}Local`]: { | ||
[sequelize.Op.or]: { | ||
[sequelize.Op.is]: null, | ||
[sequelize.Op.eq]: '' | ||
} | ||
} | ||
} | ||
} | ||
}) | ||
} | ||
} | ||
|
||
async processRecord (record, form) { | ||
const nomenclatureFields = this.findNomenclatureFields(form) | ||
|
||
for (const nomenclatureField of nomenclatureFields) { | ||
const key = nomenclatureField.key | ||
|
||
if (record[`${key}En`] !== null && record[`${key}En`] !== '' && (record[`${key}Local`] === null || record[`${key}Local`] === '')) { | ||
if (nomenclatureField.type === 'choice') { | ||
const nomenclatures = await api.models.nomenclature.findAll({ | ||
attributes: ['labelBg'], | ||
where: { | ||
type: nomenclatureField.nomenclature, | ||
labelEn: record[key + 'En'] | ||
} | ||
}) | ||
if (nomenclatures?.length > 0 && nomenclatures[0].labelBg) { | ||
record[key + 'Local'] = nomenclatures[0].labelBg | ||
record[key + 'Lang'] = 'bg' | ||
} else { | ||
record[key + 'Local'] = '|' | ||
record[key + 'Lang'] = null | ||
} | ||
} else if (nomenclatureField.type === 'multi') { | ||
const enValues = record[key + 'En'].split(' | ') | ||
|
||
const nomenclatures = await api.models.nomenclature.findAll({ | ||
attributes: ['labelBg', 'labelEn'], | ||
where: { | ||
type: nomenclatureField.nomenclature, | ||
labelEn: enValues | ||
} | ||
}) | ||
|
||
if (nomenclatures?.length > 0 && nomenclatures.length === enValues.length) { | ||
record[key + 'Local'] = enValues.map((enValue) => { | ||
const nomenclature = nomenclatures.find((nomenclature) => nomenclature.labelEn === enValue) | ||
return nomenclature?.labelBg | ||
}).filter(Boolean).join(' | ') | ||
record[key + 'Lang'] = 'bg' | ||
} else { | ||
record[key + 'Local'] = '|' | ||
record[key + 'Lang'] = null | ||
} | ||
} | ||
} | ||
} | ||
|
||
await api.forms.trySave(record, api.forms[form]) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters