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

SOROKA-73: добавляет возможность работы с датами #4

Merged
merged 8 commits into from
Jun 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,8 @@ lint:
build:
docker-compose build

.PHONY: migrate
migrate:
docker exec -it soroka-backend npm run migrate

.DEFAULT_GOAL := build
21 changes: 21 additions & 0 deletions src/controllers/dates/DateCatalog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Request, Response } from "express"
import DateCatalogService from '../../services/dates/DateCatalog'

class DateCatalogController {
private dateCatalogService: DateCatalogService

constructor() {
this.dateCatalogService = new DateCatalogService()
}

list = async (request: Request, response: Response) => {
const dateStart = Number(request.query.dateStart)
const dateEnd = Number(request.query.dateEnd)

const properties = await this.dateCatalogService.list(dateStart, dateEnd)

return response.send(properties)
}
}

export default DateCatalogController
32 changes: 32 additions & 0 deletions src/core/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,38 @@
}
}
}
},
"/dates": {
"get": {
"description": "Свойства по карточке",
"tags": ["dates"],
"parameters": [
{
"name": "dateStart",
"in": "query",
"required": true,
"type": "number",
"example": 2459727
},
{
"name": "dateEnd",
"in": "query",
"required": true,
"type": "number",
"example": 2459827
}
],
"responses": {
"200": {
"name": "obj",
"in": "body",
"description": "Свойства, соответствующие фильтру",
"schema": {
"$ref": "#/definitions/FilledPropertiesResponse"
}
}
}
}
}
},
"definitions": {
Expand Down
28 changes: 28 additions & 0 deletions src/migrations/20220531093736-calendar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use strict';
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.createTable('Calendars', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
name: {
allowNull: false,
type: Sequelize.STRING
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
async down(queryInterface, Sequelize) {
await queryInterface.dropTable('Calendars');
}
};
42 changes: 42 additions & 0 deletions src/migrations/20220531102806-date-catalog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
'use strict';
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.createTable('DateCatalogs', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
filledPropertyId: {
type: Sequelize.DataTypes.INTEGER,
references: {
model: {
tableName: 'FilledProperties',
},
key: 'id'
},
allowNull: false
},
dateStart: {
allowNull: false,
type: Sequelize.FLOAT
},
dateEnd: {
allowNull: false,
type: Sequelize.FLOAT
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
async down(queryInterface, Sequelize) {
await queryInterface.dropTable('DateCatalogs');
}
};
37 changes: 36 additions & 1 deletion src/models/cards/FilledProperty.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
import { Table, Column, Model, AllowNull, ForeignKey, BelongsToMany, DataType as DT } from 'sequelize-typescript'
import {
Table,
Column,
Model,
AllowNull,
ForeignKey,
BelongsToMany,
DataType as DT,
BeforeUpdate
} from 'sequelize-typescript'
import Card, { FilledPropertyCard } from './Card'
import DataType from './DataType'
import DateCatalog from '../dates/DateCatalog'
import Property from './Property'

@Table
Expand All @@ -18,6 +29,30 @@ class FilledProperty extends Model {

@BelongsToMany(() => Card, () => FilledPropertyCard)
cardsList: Card[]

@BeforeUpdate
static async onJulianDateChanged(instance: FilledProperty) {
// FIXME: добавить BelongsTo во всех связанных моделях
// чтобы делать запросы через related getter
const property = await Property.findByPk(instance.propertyId)
const dataType = await DataType.findByPk(property?.dataTypeId)

const isJulianDate = dataType?.name === 'JULIAN_DATE'

if (isJulianDate) {
const data: any = JSON.parse(instance.data)

// FIXME: в будущем будут периоды дат и тд
// сейчас просто заглушка для определения
// даты начала и окончания
const dateStart = data[0].jd
const dateEnd = data[0].jd

const filledPropertyId = instance.id

await DateCatalog.create({ dateStart, dateEnd, filledPropertyId })
}
}
}

export default FilledProperty
10 changes: 10 additions & 0 deletions src/models/dates/Calendar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Table, Column, Model, AllowNull } from 'sequelize-typescript'

@Table
class Calendar extends Model {
@AllowNull(false)
@Column
name: string
}

export default Calendar
25 changes: 25 additions & 0 deletions src/models/dates/DateCatalog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Table, Column, Model, AllowNull, ForeignKey, Scopes, DataType as DT } from 'sequelize-typescript'
import FilledProperty from '../cards/FilledProperty'

@Scopes(() => ({
properties: {
attributes: ['filledPropertyId']
}
}))
@Table
class DateCatalog extends Model {
@AllowNull(false)
@Column(DT.FLOAT)
dateStart: string

@AllowNull(false)
@Column(DT.FLOAT)
dateEnd: string

@AllowNull(false)
@ForeignKey(() => FilledProperty)
@Column
filledPropertyId: number
}

export default DateCatalog
12 changes: 11 additions & 1 deletion src/models/users/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,23 @@ import {
AfterCreate,
BeforeCreate,
BeforeUpdate,
ForeignKey
ForeignKey,
DefaultScope,
Scopes
} from 'sequelize-typescript'
import hashPassword from '../../utils/hashPassword'
import AuthorizationLink from '../auth/AuthorizationLink'
import Organization from '../organizations/Organization'
import UserRole from './UserRole'

@DefaultScope(() => ({
attributes: ['id', 'name', 'email', 'hasAcceptTermsOfUse', 'userRole', 'organization']
}))
@Scopes(() => ({
auth: {
attributes: ['id', 'email', 'password']
}
}))
@Table
class User extends Model {
@AllowNull(false)
Expand Down
6 changes: 5 additions & 1 deletion src/providers/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import CardTemplate from '../models/cards/CardTemplate'
import DataType from '../models/cards/DataType'
import FilledProperty from '../models/cards/FilledProperty'
import Property from '../models/cards/Property'
import Calendar from '../models/dates/Calendar'
import DateCatalog from '../models/dates/DateCatalog'
import Organization from '../models/organizations/Organization'
import User from '../models/users/User'
import UserRole from '../models/users/UserRole'
Expand All @@ -27,7 +29,9 @@ const models = [
DataType, Property,
FilledProperty, Card,
CardTemplate,
FilledPropertyCard
FilledPropertyCard,
DateCatalog,
Calendar
]

sequelize.addModels(models)
Expand Down
5 changes: 4 additions & 1 deletion src/routes/admin/admin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@ const FilledProperty = sequelize.model('FilledProperty')
const CardTemplate = sequelize.model('CardTemplate')
const Card = sequelize.model('Card')
const FilledPropertyCard = sequelize.model('FilledPropertyCard')
const DateCatalog = sequelize.model('DateCatalog')
const Calendar = sequelize.model('Calendar')

const adminJs = new AdminJS({
resources: [
User, UserRole, Organization,
AuthorizationLink, RefreshToken,
DataType, Property, FilledProperty,
CardTemplate, Card, FilledPropertyCard
CardTemplate, Card, FilledPropertyCard,
DateCatalog, Calendar
],
branding: {
companyName: 'AdminJS',
Expand Down
11 changes: 11 additions & 0 deletions src/routes/v1/dates/DateCatalog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import DateCatalogController from '../../../controllers/dates/DateCatalog'
import express from "express"

const router: express.Router = express.Router()

const controller: DateCatalogController = new DateCatalogController()

router.route('/')
.get(controller.list)

export default router
2 changes: 2 additions & 0 deletions src/routes/v1/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import filledPropertiesRoutes from "./cards/FilledProperty"
import cardRoutes from "./cards/Card"
import cardTemplateRoutes from "./cards/CardTemplate"
import organizationRoutes from "./organizations/Organization"
import dateRoutes from "./dates/DateCatalog"

const router: express.Router = express.Router()

Expand All @@ -18,5 +19,6 @@ router.use('/cards/properties', propertyRoutes)
router.use('/cards/filled-properties', filledPropertiesRoutes)
router.use('/authorization-link', authorizationLinkRoutes)
router.use('/organizations', organizationRoutes)
router.use('/dates', dateRoutes)

export default router
26 changes: 26 additions & 0 deletions src/services/dates/DateCatalog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import FilledProperty from "../../models/cards/FilledProperty"
import DateCatalog from "../../models/dates/DateCatalog"
import { Op } from 'sequelize'

class DateCatalogService {
async list(dateStart: number, dateEnd: number) {
const filteredProperties = await DateCatalog.scope('properties').findAll({
where: {
dateStart: { [Op.gte]: dateStart },
dateEnd: { [Op.lte]: dateEnd }
}
})

const filteredPropertiesIds = filteredProperties.map((prop) => prop.filledPropertyId)

const propertiesList = await FilledProperty.findAll({
where: {
id: { [Op.in]: filteredPropertiesIds }
}
})

return propertiesList
}
}

export default DateCatalogService
2 changes: 1 addition & 1 deletion src/services/users/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class UserService {
}

async checkPassword(email: string, password: string) : Promise<any> {
const user = await User.findOne({ where: { email } })
const user = await User.scope('auth').findOne({ where: { email } })

if (user) return { user: user.toJSON(), checkPassword: checkPassword(user, password) }

Expand Down