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

Student home_country to db, CLI works and other lies #1061

Merged
merged 11 commits into from
Jul 1, 2019
2 changes: 2 additions & 0 deletions scripts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,10 @@ reset_real_db () {
docker-compose up -d db user_db
ping_psql "oodi_db" "tkt_oodi_real"
docker exec -u postgres oodi_db dropdb "tkt_oodi_real"
docker exec -u postgres oodi_db psql -c "CREATE DATABASE tkt_oodi_real"
ping_psql "oodi_user_db" "user_db_real"
docker exec -u postgres oodi_user_db dropdb "user_db_real"
docker exec -u postgres oodi_user_db psql -c "CREATE DATABASE user_db_real"
db_setup_full
docker-compose down
}
Expand Down
6 changes: 3 additions & 3 deletions services/backend/oodikone2-backend/src/routes/population.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const StudyrightService = require('../services/studyrights')
// POST instead of GET because of too long params and "sensitive" data
router.post('/v2/populationstatistics/courses', async (req, res) => {
try {
if (!req.body.year || !req.body.semesters || !req.body.studyRights) {
if (!req.body.startYear || !req.body.semesters || !req.body.studyRights) {
res.status(400).json({ error: 'The body should have a year, semester and study rights defined' })
return
}
Expand All @@ -32,9 +32,9 @@ router.post('/v2/populationstatistics/courses', async (req, res) => {
})

router.get('/v3/populationstatistics', async (req, res) => {
const { year, semesters, studyRights: studyRightsJSON } = req.query
const { startYear, semesters, studyRights: studyRightsJSON } = req.query
try {
if (!year || !semesters || !studyRightsJSON) {
if (!startYear || !semesters || !studyRightsJSON) {
res.status(400).json({ error: 'The query should have a year, semester and studyRights defined' })
return
}
Expand Down
33 changes: 19 additions & 14 deletions services/backend/oodikone2-backend/src/services/populations.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,6 @@ const formatStudentForPopulationStatistics = ({
const dateMonthsFromNow = (date, months) => moment(date).add(months, 'months').format('YYYY-MM-DD')

const getStudentsIncludeCoursesBetween = async (studentnumbers, startDate, endDate, studyright, tag) => {
const tagQuery = tag ? {
tag_id: {
[Op.eq]: tag
}
} : null

const creditsOfStudentOther = {
student_studentnumber: {
Expand Down Expand Up @@ -222,7 +217,6 @@ const getStudentsIncludeCoursesBetween = async (studentnumbers, startDate, endDa
{
model: TagStudent,
attributes: ['id'],
where: tagQuery,
include: [
{
model: Tag,
Expand All @@ -236,8 +230,20 @@ const getStudentsIncludeCoursesBetween = async (studentnumbers, startDate, endDa
studentnumber: {
[Op.in]: studentnumbers
}
}
},
})


if (tag) {
const studentsWithSearchedTag = {}
students.forEach(student => {
if (student.tag_students.some(t => t.tag.tag_id === tag)) {
studentsWithSearchedTag[student.studentnumber] = true
}
})

return students.filter(student => studentsWithSearchedTag[student.studentnumber])
}
return students
}

Expand Down Expand Up @@ -308,13 +314,13 @@ const studentnumbersWithAllStudyrightElements = async (studyRights, startDate, e
}

const parseQueryParams = query => {
const { semesters, studentStatuses, studyRights, months, year, tagYear } = query
const { semesters, studentStatuses, studyRights, months, endYear, startYear } = query
const startDate = semesters.includes('FALL') ?
`${tagYear}-${semesterStart[semesters.find(s => s === 'FALL')]}` :
`${moment(tagYear, 'YYYY').add(1, 'years').format('YYYY')}-${semesterStart[semesters.find(s => s === 'SPRING')]}`
`${startYear}-${semesterStart[semesters.find(s => s === 'FALL')]}` :
`${moment(startYear, 'YYYY').add(1, 'years').format('YYYY')}-${semesterStart[semesters.find(s => s === 'SPRING')]}`
const endDate = semesters.includes('SPRING') ?
`${moment(year, 'YYYY').add(1, 'years').format('YYYY')}-${semesterEnd[semesters.find(s => s === 'SPRING')]}` :
`${year}-${semesterEnd[semesters.find(s => s === 'FALL')]}`
`${moment(endYear, 'YYYY').add(1, 'years').format('YYYY')}-${semesterEnd[semesters.find(s => s === 'SPRING')]}` :
`${endYear}-${semesterEnd[semesters.find(s => s === 'FALL')]}`
const exchangeStudents = studentStatuses && studentStatuses.includes('EXCHANGE')
const cancelledStudents = studentStatuses && studentStatuses.includes('CANCELLED')
const nondegreeStudents = studentStatuses && studentStatuses.includes('NONDEGREE')
Expand Down Expand Up @@ -422,7 +428,6 @@ const optimizedStatisticsOf = async (query) => {
) {
return { error: 'Student status should be either CANCELLED or EXCHANGE or NONDEGREE' }
}

const {
studyRights, startDate, months, endDate, exchangeStudents, cancelledStudents, nondegreeStudents
} = parseQueryParams(query)
Expand Down Expand Up @@ -550,7 +555,7 @@ const bottlenecksOf = async (query) => {

course.credits.forEach(credit => {
const { studentnumber, passingGrade, improvedGrade, failingGrade, grade, date } = parseCreditInfo(credit)
const semester = getPassingSemester(parseInt(query.year, 10), date)
const semester = getPassingSemester(parseInt(query.endYear, 10), date)
coursestats.markCredit(studentnumber, grade, passingGrade, failingGrade, improvedGrade, semester)
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ const semesters = {

const createQueryObject = (year, semester, codes, months) => ({
studyRights: codes,
year,
tagYear: year,
endYear: year,
startYear: year,
semesters: [semester],
months
})
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.addColumn('student', 'home_country_en', { type: Sequelize.STRING })
await queryInterface.addColumn('student', 'home_country_fi', { type: Sequelize.STRING })
await queryInterface.addColumn('student', 'home_country_sv', { type: Sequelize.STRING })
},
down: async () => {
await queryInterface.removeColumn('student', 'home_country_en')
await queryInterface.removeColumn('student', 'home_country_fi')
await queryInterface.removeColumn('student', 'home_country_sv')
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.removeColumn('student', 'country')
},
down: async () => {
await queryInterface.addColumn('student', 'country', { type: Sequelize.STRING })

}
}
4 changes: 3 additions & 1 deletion services/backend/shared/models/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,6 @@ const Student = sequelize.define('student',
abbreviatedname: { type: Sequelize.STRING },
birthdate: { type: Sequelize.DATE },
communicationlanguage: { type: Sequelize.STRING },
country: { type: Sequelize.STRING },
creditcount: { type: Sequelize.INTEGER },
dateofuniversityenrollment: { type: Sequelize.DATE },
matriculationexamination: { type: Sequelize.STRING },
Expand All @@ -214,6 +213,9 @@ const Student = sequelize.define('student',
country_fi: { type: Sequelize.STRING },
country_sv: { type: Sequelize.STRING },
country_en: { type: Sequelize.STRING },
home_country_fi: { type: Sequelize.STRING },
home_country_sv: { type: Sequelize.STRING },
home_country_en: { type: Sequelize.STRING },
gender_code: { type: Sequelize.INTEGER },
gender_fi: { type: Sequelize.STRING },
gender_sv: { type: Sequelize.STRING },
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React, { useEffect } from 'react'
import { withRouter } from 'react-router'
import { connect } from 'react-redux'
import { string, func, arrayOf, shape } from 'prop-types'
import { getFaculties } from '../../../redux/faculties'
import { getTextIn } from '../../../common'
import SortableTable from '../../SortableTable'



const FacultySelector = ({ language, handleSelect, dispatchGetFaculties, faculties }) => {
const fetchFaculties = async () => {
await dispatchGetFaculties()
}
useEffect(() => {
fetchFaculties()
}, [])

if (!faculties) return null
const headers = [
{
key: 'name',
title: 'name',
getRowVal: faculty => getTextIn(faculty.name, language)
},
{
key: 'code',
title: 'code',
getRowVal: faculty => faculty.code
}
]


return (
<SortableTable
columns={headers}
getRowKey={faculty => faculty.code}
getRowProps={faculty => ({ onClick: () => handleSelect(faculty.code), style: { cursor: 'pointer' } })}
data={faculties}
/>
)
}
FacultySelector.propTypes = {
language: string.isRequired,
handleSelect: func.isRequired,
dispatchGetFaculties: func.isRequired,
faculties: arrayOf(shape({})).isRequired
}

const mapStateToProps = ({ faculties, settings }) => ({
faculties: faculties.data,
language: settings.language
})

export default connect(mapStateToProps, { dispatchGetFaculties: getFaculties })(withRouter(FacultySelector))
18 changes: 18 additions & 0 deletions services/oodikone2-frontend/src/components/Faculty/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react'
import { withRouter } from 'react-router'
import { Header, Segment } from 'semantic-ui-react'
import FacultySelector from './FacultySelector'

const Faculty = () => (
<div className="segmentContainer">
<Header className="segmentTitle" size="large">
Faculties
</Header>
<Segment className="contentSegment" >
<FacultySelector />
</Segment>
</div>
)


export default withRouter(Faculty)
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,11 @@ class PopulationCourseStats extends Component {
clearCourseStats: clearCourseStatsfn,
years
} = this.props

const yearCode = year => Object.values(years).find(yearObject =>
yearObject.yearname.slice(0, 4).includes(year)).yearcode
const { year, months } = query
const fromYear = yearCode(year)
const toYear = yearCode(moment(moment(year, 'YYYY').add(months, 'months')).format('YYYY'))
const { startYear, months } = query
const fromYear = yearCode(startYear)
const toYear = yearCode(moment(moment(startYear, 'YYYY').add(months, 'months')).format('YYYY'))
history.push('/coursestatistics/')
clearCourseStatsfn()
getStatsFn({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const PopulationQueryCard =
history.push('/populations')
removeSampleFn(uuid)
}
const { uuid, year, semesters, months, studentStatuses } = query
const { uuid, startYear, semesters, months, studentStatuses } = query
const { students } = population
if (students.length > 0) {
return (
Expand All @@ -40,19 +40,19 @@ const PopulationQueryCard =
<div className="dateItem">
<Icon name="calendar" size="small" />
{`${semesters.map(s => translate(`populationStatistics.${s}`))}/
${year}-${Number(year) + 1}, showing ${months} months.`}
${startYear}-${Number(startYear) + 1}, showing ${months} months.`}
</div>
<div>
{`${translate('populationStatistics.sampleSize', { amount: students.length })} `}
</div>
<div>
{`Updated at ${reformatDate(_.minBy(students, 'updatedAt').updatedAt, DISPLAY_DATE_FORMAT)} `}
</div>
<div>{studentStatuses.includes('EXCHANGE') ? 'Includes' : 'Excludes' } exchange students</div>
<div>{studentStatuses.includes('CANCELLED') ? 'Includes ' : 'Excludes ' }
<div>{studentStatuses.includes('EXCHANGE') ? 'Includes' : 'Excludes'} exchange students</div>
<div>{studentStatuses.includes('CANCELLED') ? 'Includes ' : 'Excludes '}
students with cancelled study right
</div>
<div>{studentStatuses.includes('NONDEGREE') ? 'Includes ' : 'Excludes ' }
<div>{studentStatuses.includes('NONDEGREE') ? 'Includes ' : 'Excludes '}
students with non-degree study right
</div>
{updating ?
Expand Down Expand Up @@ -83,7 +83,7 @@ const PopulationQueryCard =
<Card.Meta>
<div className="dateItem">
<Icon name="calendar" size="small" />
{`${semesters.map(s => translate(`populationStatistics.${s}`))}/${year}-${Number(year) + 1},
{`${semesters.map(s => translate(`populationStatistics.${s}`))}/${startYear}-${Number(startYear) + 1},
showing ${months} months.`}
</div>
<div>
Expand All @@ -109,7 +109,7 @@ PopulationQueryCard.propTypes = {
translate: func.isRequired,
population: shape({ students: arrayOf(object), extents: arrayOf(object) }).isRequired,
query: shape({
year: oneOfType([string, number]),
startYear: oneOfType([string, number]),
semester: string,
studyRights: shape({ programme: string, degree: string, studyTrack: string }),
uuid: string
Expand Down
Loading