feat(ratecard): add currency field to rate card queries and update logic
This commit is contained in:
@@ -29,7 +29,7 @@ public static async get(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise<
|
|||||||
(
|
(
|
||||||
SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(t))), '[]'::JSON)
|
SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(t))), '[]'::JSON)
|
||||||
FROM (
|
FROM (
|
||||||
SELECT id, name, team_id, created_at, updated_at
|
SELECT id, name, team_id, currency, created_at, updated_at
|
||||||
FROM finance_rate_cards
|
FROM finance_rate_cards
|
||||||
WHERE team_id = $1 ${searchQuery}
|
WHERE team_id = $1 ${searchQuery}
|
||||||
ORDER BY ${sortField} ${sortOrder}
|
ORDER BY ${sortField} ${sortOrder}
|
||||||
@@ -49,7 +49,7 @@ public static async get(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise<
|
|||||||
@HandleExceptions()
|
@HandleExceptions()
|
||||||
public static async getById(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise<IWorkLenzResponse> {
|
public static async getById(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise<IWorkLenzResponse> {
|
||||||
const q = `
|
const q = `
|
||||||
SELECT id, name, team_id, created_at, updated_at
|
SELECT id, name, team_id, currency, created_at, updated_at
|
||||||
FROM finance_rate_cards
|
FROM finance_rate_cards
|
||||||
WHERE id = $1 AND team_id = $2;
|
WHERE id = $1 AND team_id = $2;
|
||||||
`;
|
`;
|
||||||
@@ -62,11 +62,11 @@ public static async get(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise<
|
|||||||
public static async update(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise<IWorkLenzResponse> {
|
public static async update(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise<IWorkLenzResponse> {
|
||||||
const q = `
|
const q = `
|
||||||
UPDATE finance_rate_cards
|
UPDATE finance_rate_cards
|
||||||
SET name = $3, updated_at = NOW()
|
SET name = $3, currency = $4, updated_at = NOW()
|
||||||
WHERE id = $1 AND team_id = $2
|
WHERE id = $1 AND team_id = $2
|
||||||
RETURNING id, name, team_id, created_at, updated_at;
|
RETURNING id, name, team_id, currency, created_at, updated_at;
|
||||||
`;
|
`;
|
||||||
const result = await db.query(q, [req.params.id, req.user?.team_id || null, req.body.name]);
|
const result = await db.query(q, [req.params.id, req.user?.team_id || null, req.body.name, req.body.currency]);
|
||||||
const [data] = result.rows;
|
const [data] = result.rows;
|
||||||
return res.status(200).send(new ServerResponse(true, data));
|
return res.status(200).send(new ServerResponse(true, data));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ export const updateRateCard = createAsyncThunk(
|
|||||||
async ({ id, body }: { id: string; body: RatecardType }, { rejectWithValue }) => {
|
async ({ id, body }: { id: string; body: RatecardType }, { rejectWithValue }) => {
|
||||||
try {
|
try {
|
||||||
const response = await rateCardApiService.updateRateCard(id, body);
|
const response = await rateCardApiService.updateRateCard(id, body);
|
||||||
|
console.log('response', response);
|
||||||
return response.body;
|
return response.body;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('Update RateCard', error);
|
logger.error('Update RateCard', error);
|
||||||
|
|||||||
@@ -3,14 +3,12 @@ import React, { useEffect, useMemo, useState } from 'react';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useAppSelector } from '../../../hooks/useAppSelector';
|
import { useAppSelector } from '../../../hooks/useAppSelector';
|
||||||
import { useAppDispatch } from '../../../hooks/useAppDispatch';
|
import { useAppDispatch } from '../../../hooks/useAppDispatch';
|
||||||
import { fetchData } from '../../../utils/fetchData';
|
|
||||||
import { fetchRateCardById, fetchRateCards, toggleRatecardDrawer, updateRateCard } from '../finance-slice';
|
import { fetchRateCardById, fetchRateCards, toggleRatecardDrawer, updateRateCard } from '../finance-slice';
|
||||||
import { RatecardType, IJobType } from '@/types/project/ratecard.types';
|
import { RatecardType, IJobType } from '@/types/project/ratecard.types';
|
||||||
import { IJobTitlesViewModel } from '@/types/job.types';
|
import { IJobTitlesViewModel } from '@/types/job.types';
|
||||||
import { DEFAULT_PAGE_SIZE } from '@/shared/constants';
|
import { DEFAULT_PAGE_SIZE } from '@/shared/constants';
|
||||||
import { jobTitlesApiService } from '@/api/settings/job-titles/job-titles.api.service';
|
import { jobTitlesApiService } from '@/api/settings/job-titles/job-titles.api.service';
|
||||||
import { DeleteOutlined } from '@ant-design/icons';
|
import { DeleteOutlined } from '@ant-design/icons';
|
||||||
import { rateCardApiService } from '@/api/settings/rate-cards/rate-cards.api.service';
|
|
||||||
|
|
||||||
interface PaginationType {
|
interface PaginationType {
|
||||||
current: number;
|
current: number;
|
||||||
@@ -36,20 +34,16 @@ const RatecardDrawer = ({
|
|||||||
|
|
||||||
const { t } = useTranslation('settings/ratecard-settings');
|
const { t } = useTranslation('settings/ratecard-settings');
|
||||||
// get drawer state from client reducer
|
// get drawer state from client reducer
|
||||||
const drawerLoading = useAppSelector(state => state.financeReducer.drawerLoading);
|
const drawerLoading = useAppSelector(state => state.financeReducer.isFinanceDrawerloading);
|
||||||
const drawerRatecard = useAppSelector(state => state.financeReducer.drawerRatecard);
|
const drawerRatecard = useAppSelector(state => state.financeReducer.drawerRatecard);
|
||||||
const isDrawerOpen = useAppSelector(
|
const isDrawerOpen = useAppSelector(
|
||||||
(state) => state.financeReducer.isRatecardDrawerOpen
|
(state) => state.financeReducer.isRatecardDrawerOpen
|
||||||
);
|
);
|
||||||
// get currently using currency from finance reducer
|
|
||||||
const cur = useAppSelector(
|
|
||||||
(state) => state.financeReducer.currency
|
|
||||||
).toUpperCase();
|
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const [isAddingRole, setIsAddingRole] = useState(false);
|
const [isAddingRole, setIsAddingRole] = useState(false);
|
||||||
const [selectedJobTitleId, setSelectedJobTitleId] = useState<string | undefined>(undefined);
|
const [selectedJobTitleId, setSelectedJobTitleId] = useState<string | undefined>(undefined);
|
||||||
const [searchQuery, setSearchQuery] = useState('');
|
const [searchQuery, setSearchQuery] = useState('');
|
||||||
const [currency, setCurrency] = useState(cur);
|
const [currency, setCurrency] = useState('LKR');
|
||||||
const [name, setName] = useState<string>('Untitled Rate Card');
|
const [name, setName] = useState<string>('Untitled Rate Card');
|
||||||
const [jobTitles, setJobTitles] = useState<IJobTitlesViewModel>({});
|
const [jobTitles, setJobTitles] = useState<IJobTitlesViewModel>({});
|
||||||
const [pagination, setPagination] = useState<PaginationType>({
|
const [pagination, setPagination] = useState<PaginationType>({
|
||||||
@@ -99,7 +93,7 @@ const RatecardDrawer = ({
|
|||||||
if (type === 'update' && drawerRatecard) {
|
if (type === 'update' && drawerRatecard) {
|
||||||
setRoles(drawerRatecard.jobRolesList || []);
|
setRoles(drawerRatecard.jobRolesList || []);
|
||||||
setName(drawerRatecard.name || '');
|
setName(drawerRatecard.name || '');
|
||||||
setCurrency(drawerRatecard.currency || cur);
|
setCurrency(drawerRatecard.currency || 'LKR');
|
||||||
}
|
}
|
||||||
}, [drawerRatecard, type]);
|
}, [drawerRatecard, type]);
|
||||||
|
|
||||||
@@ -119,11 +113,11 @@ const RatecardDrawer = ({
|
|||||||
const jobTitle = jobTitles.data?.find(jt => jt.id === jobTitleId);
|
const jobTitle = jobTitles.data?.find(jt => jt.id === jobTitleId);
|
||||||
if (jobTitle) {
|
if (jobTitle) {
|
||||||
const newRole = {
|
const newRole = {
|
||||||
jobId: jobTitleId,
|
rate_card_id: jobTitleId,
|
||||||
jobTitle: jobTitle.name || 'New Role',
|
jobTitle: jobTitle.name || 'New Role',
|
||||||
ratePerHour: 0,
|
ratePerHour: 0,
|
||||||
};
|
};
|
||||||
setRoles([...roles, newRole]);
|
// setRoles([...roles, newRole]);
|
||||||
}
|
}
|
||||||
setIsAddingRole(false);
|
setIsAddingRole(false);
|
||||||
setSelectedJobTitleId(undefined);
|
setSelectedJobTitleId(undefined);
|
||||||
@@ -239,13 +233,13 @@ const RatecardDrawer = ({
|
|||||||
<Flex gap={8} align="center">
|
<Flex gap={8} align="center">
|
||||||
<Typography.Text>{t('currency')}</Typography.Text>
|
<Typography.Text>{t('currency')}</Typography.Text>
|
||||||
<Select
|
<Select
|
||||||
value={currency.toLowerCase()}
|
value={currency}
|
||||||
options={[
|
options={[
|
||||||
{ value: 'lkr', label: 'LKR' },
|
{ value: 'LKR', label: 'LKR' },
|
||||||
{ value: 'usd', label: 'USD' },
|
{ value: 'USD', label: 'USD' },
|
||||||
{ value: 'inr', label: 'INR' },
|
{ value: 'INR', label: 'INR' },
|
||||||
]}
|
]}
|
||||||
onChange={(value) => setCurrency(value.toUpperCase())}
|
onChange={(value) => setCurrency(value)}
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|||||||
Reference in New Issue
Block a user