Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnPetros committed Nov 30, 2024
2 parents ffc4877 + a8a8a6f commit 7e9990d
Show file tree
Hide file tree
Showing 25 changed files with 167 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,21 @@ import { HTTP_STATUS_CODE } from '@stocker/core/constants'

type RouteParams = {
page: string
name?: string
}

export class ListCategoryController {
async handle(http: IHttp) {
const { companyId } = await http.getUser()
const { page } = http.getQueryParams<RouteParams>()
const { page, name } = http.getQueryParams<RouteParams>()
const pageNumber = parseInt(page || '1', 10)

const useCase = new ListCategoryUseCase(categoriesRepository)
const response = await useCase.execute({ page: pageNumber, companyId: companyId })
const response = await useCase.execute({
page: pageNumber,
companyId: companyId,
name: name,
})

return http.send(response, HTTP_STATUS_CODE.ok)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,28 @@ import { inventoryMovementsRepository } from '@/database'
type QueryParams = {
page?: string
productId?: string
employeeId?: string
startDate?: string
endDate?: string
movementType?: 'inbound' | 'outbound'
}

export class ListInventoryMovementsController {
async handle(http: IHttp) {
const { page, productId } = http.getQueryParams<QueryParams>()
const { page, productId, employeeId, startDate, endDate, movementType } =
http.getQueryParams<QueryParams>()
const { companyId } = await http.getUser()
const useCase = new ListInventoryMovementsUseCase(inventoryMovementsRepository)
const pageNumber = parseInt(page || '1', 10)
const result = await useCase.execute({
page: pageNumber,
productId: productId,
companyId: companyId
})
const params = {
page: page ? parseInt(page, 10) : undefined,
companyId,
productId,
employeeId,
movementType,
startDate: startDate ? new Date(startDate) : undefined,
endDate: endDate ? new Date(endDate) : undefined,
}
const result = await useCase.execute(params)
return http.send(result, HTTP_STATUS_CODE.ok)
}
}
1 change: 1 addition & 0 deletions apps/server/src/api/controllers/locations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export { RegisterLocationController } from './register-location-controller'
export {GetLocationController} from "./get-location-controller"
export { DeleteLocationsController } from './delete-locations-controller'
export { UpdateLocationController } from './update-location-controller'
export { ListLocationsController } from './list-locations-controller'
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import { locationsRepository } from '@/database'
import type { IHttp } from '@stocker/core/interfaces'
import { ListLocationsUseCase } from '@stocker/core/use-cases'

import { locationsRepository } from '@/database'
import { HTTP_STATUS_CODE } from '@stocker/core/constants'

type RouteParams = {
page: string
type QueryParams = {
page: number
name?: string
}

export class ListLocationsController {
async handle(http: IHttp) {
const { companyId } = await http.getUser()
const { page } = http.getQueryParams<RouteParams>()
const pageNumber = parseInt(page || '1', 10)
const user = await http.getUser()
const companyId = user.companyId
const { page, name } = http.getQueryParams<QueryParams>()

const useCase = new ListLocationsUseCase(locationsRepository)
const response = await useCase.execute({ page: pageNumber, companyId: companyId })
return http.send(response, HTTP_STATUS_CODE.ok)
const locationsDto = await useCase.execute({ companyId, page, name })

return http.send(locationsDto)
}
}
4 changes: 2 additions & 2 deletions apps/server/src/app/fastify/routes/locations-routes.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { DeleteLocationsController, GetLocationController, RegisterLocationController } from "@/api/controllers/locations";
import type { FastifyInstance } from "fastify";
import { FastifyHttp } from "../fastify-http";
import { UpdateLocationController } from "@/api/controllers/locations/update-location-controller";
import { ListLocationsController } from "@/api/controllers/locations/list-locations-controller";
import { UpdateLocationController } from '@/api/controllers/locations/update-location-controller'
import { ListLocationsController } from '@/api/controllers/locations/list-locations-controller'

export const LocationsRoutes = async (app: FastifyInstance) => {
const registerLocationController = new RegisterLocationController()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Location } from '@stocker/core/entities'
import type { PrismaLocations } from '../types'
import type { PrismaLocation } from '../types'

export class PrismaLocationsMapper {
toDomain(prismaLocation: PrismaLocations): Location {
toDomain(prismaLocation: PrismaLocation): Location {
return Location.create({
id: prismaLocation.id,
name: prismaLocation.name,
Expand All @@ -18,7 +18,7 @@ export class PrismaLocationsMapper {
});
}

toPrisma(location: Location): PrismaLocations {
toPrisma(location: Location): PrismaLocation {
const locationDto = location.dto;

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export class PrismaCategoriesRepository implements ICategoriesRepository {
}
}

async findMany({ page, companyId }: CategoriesListParams): Promise<Category[]> {
async findMany({ page, companyId, name }: CategoriesListParams): Promise<Category[]> {
try {
const prismaCategories = await prisma.category.findMany({
take: PAGINATION.itemsPerPage,
Expand All @@ -71,9 +71,17 @@ export class PrismaCategoriesRepository implements ICategoriesRepository {
where: {
parent_category_id: null,
company_id: companyId,
name: name ?? undefined,
},
orderBy: { registered_at: 'desc' },
})
const count = await prisma.category.count({
where: {
parent_category_id: null,
company_id: companyId,
name: name ?? undefined,
},
})

return prismaCategories.map(this.mapper.toDomain)
} catch (error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export class PrismaInventoryMovementsRepository implements IInventoryMovementsRe
movementType,
productId,
companyId,
employeeId,
}: InventoryMovementsListParams) {
try {
const whereCondition = productId ? { product_id: productId } : undefined
Expand Down Expand Up @@ -123,12 +124,18 @@ export class PrismaInventoryMovementsRepository implements IInventoryMovementsRe
productIdFilter = { product_id: productId }
}

let employeeIdFilter = {}
if (employeeId) {
employeeIdFilter = { employee_id: employeeId }
}

const prismaInventoryMovements = await prisma.inventoryMovement.findMany({
...paginationParams,
where: {
...productIdFilter,
...movementTypeFilter,
...dateRangeParams,
...employeeIdFilter,
Product: {
company_id: companyId,
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Location } from '@stocker/core/entities'
import type { ILocationsRepository } from '@stocker/core/interfaces'
import type { PaginationResponse } from '@stocker/core/responses'
import type { CategoriesListParams } from '@stocker/core/types'
import { PaginationResponse } from '@stocker/core/responses'
import type { CategoriesListParams, LocationsListParams } from '@stocker/core/types'
import { prisma } from '../prisma-client'
import { PrismaError } from '../prisma-error'
import { PAGINATION } from '@stocker/core/constants'
Expand Down Expand Up @@ -102,27 +102,35 @@ export class PrismaLocationsRepository implements ILocationsRepository {
}
}

async findMany(params: CategoriesListParams): Promise<Location[]> {
async findMany(params: LocationsListParams): Promise<{locations: Location[], count: number}> {
try {
const prismaLocations = await prisma.location.findMany({
take: PAGINATION.itemsPerPage,
skip: params.page > 0 ? (params.page - 1) * PAGINATION.itemsPerPage : 1,
where: {
company_id: params.companyId,
parent_location_id: null,
name: params.name
},
include: {
subLocation: true,
},
orderBy: { registered_at: 'desc' },
})
const count = await prisma.location.count({
where: {
company_id: params.companyId,
parent_location_id: null,
},
})

const locations = prismaLocations.map(this.mapper.toDomain)
return locations
return {locations, count}
} catch (error) {
throw new PrismaError(error)
}
}

async count(): Promise<number> {
try {
const count = await prisma.location.count()
Expand Down
2 changes: 1 addition & 1 deletion apps/server/src/database/prisma/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ export type { PrismaUser } from './prisma-user'
export type { PrismaStockLevelNotification } from './prisma-stock-level-notification'
export type { PrismaExpirationDateNotification } from './prisma-expiration-date-notification'
export type { PrismaSupplier } from './prisma-suppliers'
export type { PrismaLocation } from './prisma-locations'
export type { PrismaLocation } from './prisma-location'
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Location } from '@prisma/client'

export type PrismaLocation = Location & {
subLocation?: Location[]
subLocation: Location[]
}
2 changes: 1 addition & 1 deletion apps/server/src/database/prisma/types/prisma-product.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { Product } from '@prisma/client'
import type { PrismaBatch } from './prisma-batch'
import type { PrismaCategory } from './prisma-category'
import type { PrismaSupplier } from './prisma-suppliers'
import type { PrismaLocation } from './prisma-locations'
import type { PrismaLocation } from './prisma-location'

export type PrismaProduct = Product & {
batches: PrismaBatch[]
Expand Down
1 change: 1 addition & 0 deletions apps/web/src/api/middlewares/verify-jwt-middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { IController, IHttp } from '@stocker/core/interfaces'

const PRIVATE_ROUTES = [
'/',
ROUTES.categories,
ROUTES.dashboard,
ROUTES.profile,
...Object.values(ROUTES.inventory),
Expand Down
4 changes: 3 additions & 1 deletion apps/web/src/api/services/users-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ export const UsersService = (apiClient: IApiClient): IUsersService => {
return await apiClient.get<UserDto>(`/users/${userId}`)
},

async listUsers({ page }) {
async listUsers({ page,name,role }) {
apiClient.setParam('name',String(name))
apiClient.setParam('role',String(role))
apiClient.setParam('page', String(page))
return await apiClient.get<PaginationResponse<UserDto>>('/users')
},
Expand Down
1 change: 1 addition & 0 deletions apps/web/src/constants/routes.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export const ROUTES = {
dashboard: '/dashboard',
categories: '/categories',
inventory: {
stocks: '/inventory/stocks',
productStock: '/inventory/stocks/:routeParam',
Expand Down
1 change: 1 addition & 0 deletions apps/web/src/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const config: MiddlewareConfig = {
'/inventory/:path*',
'/inventory/stocks/:productId*',
'/records/:path*',
'/categories/:path*',
],
}

Expand Down
33 changes: 30 additions & 3 deletions apps/web/src/ui/components/pages/employees/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client'

import { Button } from '@nextui-org/react'
import { Button, Select, SelectItem } from '@nextui-org/react'

import { Drawer } from '../../commons/drawer'
import { Search } from '../../commons/search'
Expand All @@ -22,14 +22,41 @@ export const EmployeesPage = () => {
handleEmployeesSelectionChange,
handlePageChange,
handleDeleteEmployeesAlertDialogConfirm,
handleNameSearchChange,
nameSearchValue,
roleSearchValue,
handleRoleSearchChange,
} = useEmployeesPage()
return (
<>
<div className='space-y-5'>
<div className='flex flex-col gap-3 md:flex-row md:gap-0 justify-between'>
<div className='flex-1 w-full max-w-96 space-y-2'>
<div className='flex-1 w-full space-y-2'>
<h1 className='text-3xl font-black'>Funcionários</h1>
<Search value={''} onSearchChange={() => {}} />
<div className=' flex md:items-center flex-col md:flex-row gap-4 w-full'>
<Search value={nameSearchValue} onSearchChange={handleNameSearchChange} />
<Select
className='max-w-96 '
color='default'
size='lg'
defaultSelectedKeys={['']}
value={roleSearchValue}
onChange={(e) =>
handleRoleSearchChange(e.target.value as '' | 'MANAGER' | 'EMPLOYEE')
}
>
<SelectItem key='' value=''>
Todos
</SelectItem>
<SelectItem key='employee' value='EMPLOYEE'>
Funcionário
</SelectItem>

<SelectItem key='manager' value='MANAGER'>
Gerente
</SelectItem>
</Select>
</div>
</div>
<div className='flex items-center justify-center gap-1'>
{selectedEmployeesIds.length > 0 && (
Expand Down
27 changes: 24 additions & 3 deletions apps/web/src/ui/components/pages/employees/use-employees-page.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,38 @@
import { CACHE } from '@/constants'
import { useApi, useCache, useToast, useUrlParamNumber } from '@/ui/hooks'
import {
useApi,
useCache,
useToast,
useUrlParamNumber,
useUrlParamString,
} from '@/ui/hooks'
import type { UserDto } from '@stocker/core/dtos'
import { useState } from 'react'
import { useAuthContext } from '../../contexts/auth-context'
import { UserRole } from '@stocker/core/types'

export function useEmployeesPage() {
const { showSuccess, showError } = useToast()
const [nameSearchValue, setNameSerchValue] = useUrlParamString('name')
const [roleSearchValue, setRoleSearchValue] = useUrlParamString('role')
const { usersService } = useApi()
const [page, setPage] = useUrlParamNumber('page', 1)
const [isDeleting, setIsDeleting] = useState<boolean>(false)
const [selectedEmployeesIds, setSelectdEmployeesIds] = useState<string[]>([])
function handlePageChange(page: number) {
setPage(page)
}
function handleRoleSearchChange(role:"MANAGER" | "EMPLOYEE" | ""){
setRoleSearchValue(role)
}
function handleNameSearchChange(name: string) {
setNameSerchValue(name)
}

const { user } = useAuthContext()
const companyId = user ? user.companyId : ''
async function fetchUsers() {
const response = await usersService.listUsers({ page, companyId: companyId })
const response = await usersService.listUsers({ page, companyId: companyId,name: nameSearchValue,role: roleSearchValue.toUpperCase() as UserRole })
if (response.isFailure) {
showError(response.errorMessage)
}
Expand All @@ -25,7 +41,7 @@ export function useEmployeesPage() {
const { data, isFetching, refetch } = useCache({
fetcher: fetchUsers,
key: CACHE.users.key,
dependencies: [page],
dependencies: [page,nameSearchValue,roleSearchValue],
})
async function handleUpdateEmployee() {
refetch()
Expand Down Expand Up @@ -67,5 +83,10 @@ export function useEmployeesPage() {
handleEmployeesSelectionChange,
selectedEmployeesIds,
handleUpdateEmployee,
nameSearchValue,
handleNameSearchChange,
handleRoleSearchChange,
roleSearchValue,

}
}
Loading

0 comments on commit 7e9990d

Please sign in to comment.