Skip to content

Commit

Permalink
Resident Date Error (#167)
Browse files Browse the repository at this point in the history
* fix bug

* lint fixes
  • Loading branch information
Connor Bechthold authored Sep 27, 2023
1 parent 8cb1d23 commit 91d7519
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 29 deletions.
9 changes: 6 additions & 3 deletions backend/app/models/residents.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ class Residents(db.Model):
id = db.Column(db.Integer, primary_key=True, nullable=False)
initial = db.Column(db.String, nullable=False)
room_num = db.Column(db.Integer, nullable=False)
date_joined = db.Column(db.DateTime(timezone=True), nullable=False)
date_left = db.Column(db.DateTime(timezone=True), nullable=True)
date_joined = db.Column(db.Date, nullable=False)
date_left = db.Column(db.Date, nullable=True)
building = db.Column(db.Enum("144", "402", "362", name="buildings"), nullable=False)

resident_id = db.column_property(initial + cast(room_num, String))
Expand All @@ -31,7 +31,10 @@ def to_dict(self, include_relationships=False):
attr = getattr(self, field)
# if it's a regular column, extract the value
if isinstance(column, ColumnProperty):
formatted[field] = attr
if (field == "date_joined" or field == "date_left") and attr:
formatted[field] = attr.strftime("%Y-%m-%d")
else:
formatted[field] = attr
# otherwise, it's a relationship field
# (currently not applicable, but may be useful for entity groups)
elif include_relationships:
Expand Down
21 changes: 11 additions & 10 deletions backend/app/services/implementations/residents_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,28 @@ def __init__(self, logger):
"""
self.logger = logger

def convert_to_date_obj(self, date):
return datetime.strptime(date, "%Y-%m-%d")

def is_date_left_invalid_resident(self, resident):
"""
Validates if date_left is greater than date_joined given a payload for a resident
"""
if "date_joined" in resident and "date_left" in resident:
date_joined = datetime.fromisoformat(
resident["date_joined"].replace("Z", "+00:00")
)
date_left = datetime.fromisoformat(
resident["date_left"].replace("Z", "+00:00")
)
if "date_joined" in resident:
resident["date_joined"] = self.convert_to_date_obj(resident["date_joined"])

if "date_left" in resident:
resident["date_left"] = self.convert_to_date_obj(resident["date_left"])

if date_left < date_joined:
if "date_joined" in resident and "date_left" in resident:
if resident["date_left"] < resident["date_joined"]:
return True

return False

def add_resident(self, resident):
new_resident = resident
try:
new_resident = Residents(**new_resident)
new_resident = Residents(**resident)
db.session.add(new_resident)
db.session.commit()
return resident
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"""update_resident_date_fields
Revision ID: 24fad25f60e3
Revises: a5d22b31faab
Create Date: 2023-09-26 19:33:15.491168
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision = "24fad25f60e3"
down_revision = "a5d22b31faab"
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table("residents", schema=None) as batch_op:
batch_op.alter_column(
"date_joined",
existing_type=postgresql.TIMESTAMP(timezone=True),
type_=sa.Date(),
existing_nullable=False,
)
batch_op.alter_column(
"date_left",
existing_type=postgresql.TIMESTAMP(timezone=True),
type_=sa.Date(),
existing_nullable=True,
)

# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table("residents", schema=None) as batch_op:
batch_op.alter_column(
"date_left",
existing_type=sa.Date(),
type_=postgresql.TIMESTAMP(timezone=True),
existing_nullable=True,
)
batch_op.alter_column(
"date_joined",
existing_type=sa.Date(),
type_=postgresql.TIMESTAMP(timezone=True),
existing_nullable=False,
)

# ### end Alembic commands ###
3 changes: 2 additions & 1 deletion frontend/src/components/forms/CreateResident.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { Col, Row } from "react-bootstrap";
import selectStyle from "../../theme/forms/selectStyles";
import { singleDatePickerStyle } from "../../theme/forms/datePickerStyles";
import ResidentAPIClient from "../../APIClients/ResidentAPIClient";
import { convertToString } from "../../helper/dateHelpers";

// TODO: Connect to Buidings table
const BUILDINGS = [
Expand Down Expand Up @@ -55,7 +56,7 @@ const CreateResident = (): React.ReactElement => {
await ResidentAPIClient.createResident({
initial: initials.toUpperCase(),
roomNum: parseInt(roomNumber, 10),
dateJoined: moveInDate.toISOString(),
dateJoined: convertToString(moveInDate),
building,
});
};
Expand Down
22 changes: 15 additions & 7 deletions frontend/src/components/forms/EditLog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import selectStyle from "../../theme/forms/selectStyles";
import { singleDatePickerStyle } from "../../theme/forms/datePickerStyles";
import { UserLabel } from "../../types/UserTypes";
import { LogRecord } from "../../types/LogRecordTypes";
import combineDateTime from "../../helper/combineDateTime";
import { combineDateTime } from "../../helper/dateHelpers";

type Props = {
logRecord: LogRecord;
Expand Down Expand Up @@ -199,7 +199,7 @@ const EditLog = ({
};

const initializeValues = () => {
// set state variables
// set state variables
setEmployee(getCurUserSelectOption());
setDate(new Date(logRecord.datetime));
setTime(
Expand All @@ -210,7 +210,9 @@ const EditLog = ({
}),
);
setBuilding(logRecord.building);
const residentId = residentOptions.find((item) => item.label === logRecord.residentId)?.value;
const residentId = residentOptions.find(
(item) => item.label === logRecord.residentId,
)?.value;
setResident(residentId !== undefined ? residentId : -1);
setTags(logRecord.tags);
setAttnTo(logRecord.attnTo !== undefined ? logRecord.attnTo : -1);
Expand Down Expand Up @@ -257,7 +259,7 @@ const EditLog = ({
tags,
building,
attnTo: attnTo === -1 ? undefined : attnTo,
})
});
if (res) {
setAlertData(ALERT_DATA.SUCCESS);
countRecords();
Expand Down Expand Up @@ -344,7 +346,9 @@ const EditLog = ({
placeholder="Building No."
onChange={handleBuildingChange}
styles={selectStyle}
defaultValue={BUILDINGS.find((item) => item.value === building)}
defaultValue={BUILDINGS.find(
(item) => item.value === building,
)}
/>
<FormErrorMessage>Building is required.</FormErrorMessage>
</FormControl>
Expand All @@ -357,7 +361,9 @@ const EditLog = ({
placeholder="Select Resident"
onChange={handleResidentChange}
styles={selectStyle}
defaultValue={residentOptions.find((item) => item.label === logRecord.residentId)}
defaultValue={residentOptions.find(
(item) => item.label === logRecord.residentId,
)}
/>
<FormErrorMessage>Resident is required.</FormErrorMessage>
</FormControl>
Expand Down Expand Up @@ -389,7 +395,9 @@ const EditLog = ({
placeholder="Select Employee"
onChange={handleAttnToChange}
styles={selectStyle}
defaultValue={employeeOptions.find((item) => item.value === logRecord.attnTo)}
defaultValue={employeeOptions.find(
(item) => item.value === logRecord.attnTo,
)}
/>
</FormControl>
</Col>
Expand Down
17 changes: 11 additions & 6 deletions frontend/src/components/forms/EditResident.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { Resident } from "../../types/ResidentTypes";
import selectStyle from "../../theme/forms/selectStyles";
import { singleDatePickerStyle } from "../../theme/forms/datePickerStyles";
import CreateToast from "../common/Toasts";
import { convertToDate, convertToString } from "../../helper/dateHelpers";

// TODO: Connect to Buidings table
const BUILDINGS = [
Expand Down Expand Up @@ -67,9 +68,9 @@ const EditResident = ({ resident, isOpen, toggleClose }: Props) => {
residentId: resident.residentId,
initial: initials.toUpperCase(),
roomNum: roomNumber,
dateJoined: moveInDate.toISOString(),
dateJoined: convertToString(moveInDate),
building: userBuilding,
dateLeft: moveOutDate?.toISOString(),
dateLeft: moveOutDate ? convertToString(moveOutDate) : undefined,
});

if (res != null) {
Expand Down Expand Up @@ -135,9 +136,11 @@ const EditResident = ({ resident, isOpen, toggleClose }: Props) => {

setInitials(resident.initial);
setRoomNumber(resident.roomNum);
setMoveInDate(new Date(resident.dateJoined));
setMoveInDate(convertToDate(resident.dateJoined));
setUserBuilding(resident.building);
setMoveOutDate(resident.dateLeft ? new Date(resident.dateLeft) : undefined);
setMoveOutDate(
resident.dateLeft ? convertToDate(resident.dateLeft) : undefined,
);

setInitialsError(false);
setRoomNumberError(false);
Expand Down Expand Up @@ -174,9 +177,11 @@ const EditResident = ({ resident, isOpen, toggleClose }: Props) => {
useEffect(() => {
setInitials(resident.initial);
setRoomNumber(resident.roomNum);
setMoveInDate(new Date(resident.dateJoined));
setMoveInDate(convertToDate(resident.dateJoined));
setUserBuilding(resident.building);
setMoveOutDate(resident.dateLeft ? new Date(resident.dateLeft) : undefined);
setMoveOutDate(
resident.dateLeft ? convertToDate(resident.dateLeft) : undefined,
);
}, [resident]);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,20 @@ import getFormattedDateAndTime from "../../../utils/DateUtils";
import AuthContext from "../../../contexts/AuthContext";
import CreateToast from "../../common/Toasts";
import ConfirmationModal from "../../common/ConfirmationModal";
import { convertToDate } from "../../../helper/dateHelpers";

type Props = {
residents: Resident[];
tableRef: RefObject<HTMLDivElement>;
};

const getFormattedDatesAndStatus = (resident: Resident) => {
const startDateObj = new Date(resident.dateJoined);
const startDateObj = convertToDate(resident.dateJoined);
const startDate = getFormattedDateAndTime(startDateObj, true);

let endDate;
if (resident.dateLeft != null) {
const endDateObj = new Date(resident.dateLeft);
const endDateObj = convertToDate(resident.dateLeft);
endDate = getFormattedDateAndTime(endDateObj, true);
}
const status =
Expand Down
40 changes: 40 additions & 0 deletions frontend/src/helper/dateHelpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Combine date and time
export const combineDateTime = (dateObj: Date, timeStr: string): Date => {
// Extract time components from timeStr
const [hours, minutes] = timeStr.split(":").map(Number);

// Create a new Date object with the combined date and time
const newDateObj = new Date(dateObj);
newDateObj.setHours(hours);
newDateObj.setMinutes(minutes);

return newDateObj;
};

/**
*
* @param dateString yyyy-mm-dd format
*/
export const convertToDate = (dateString: string): Date => {
// Split the date string into its components
const dateComponents = dateString.split("-");
const year = parseInt(dateComponents[0], 10);
const month = parseInt(dateComponents[1], 10) - 1; // Months are zero-based (0-11)
const day = parseInt(dateComponents[2], 10);

// Create a Date object using the components
return new Date(year, month, day);
};

/**
*
* @returns date string in yyyy-mm-dd format
*/
export const convertToString = (date: Date): string => {
// Get the year, month, and day components
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0"); // Months are zero-based, so add 1
const day = String(date.getDate()).padStart(2, "0");

return `${year}-${month}-${day}`;
};

0 comments on commit 91d7519

Please sign in to comment.