From 2813796cbb4d78ddfd687cdb8e281e7f910fe252 Mon Sep 17 00:00:00 2001 From: vini464 Date: Sun, 28 Jun 2026 20:54:27 -0300 Subject: [PATCH 1/6] feat: asking for guest email --- .../migrations/0010_merge_20260628_1708.py | 13 ++++ .../components/current-trip/GuestForm.tsx | 65 ++++++++++++------- 2 files changed, 54 insertions(+), 24 deletions(-) create mode 100644 api/apps/trips/migrations/0010_merge_20260628_1708.py diff --git a/api/apps/trips/migrations/0010_merge_20260628_1708.py b/api/apps/trips/migrations/0010_merge_20260628_1708.py new file mode 100644 index 00000000..091829d9 --- /dev/null +++ b/api/apps/trips/migrations/0010_merge_20260628_1708.py @@ -0,0 +1,13 @@ +# Generated by Django 6.0.6 on 2026-06-28 20:08 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("trips", "0009_route_max_bus"), + ("trips", "0009_trip_access_code_trip_is_private_trip_manager_and_more"), + ] + + operations = [] diff --git a/frontend/components/current-trip/GuestForm.tsx b/frontend/components/current-trip/GuestForm.tsx index a72abfa7..ff5a74f5 100644 --- a/frontend/components/current-trip/GuestForm.tsx +++ b/frontend/components/current-trip/GuestForm.tsx @@ -20,11 +20,12 @@ const normalizeCpf = (value: string | undefined) => { const guestSchema = z.object({ full_name: z.string().nonempty("Informe o nome completo"), + email: z.email("Informe um Email válidgo"), cpf: z .string() .refine( (val) => val.replace(/\D/g, "").length === 11, - "CPF deve ter exatamente 11 números." + "CPF deve ter exatamente 11 números.", ), trip: z.number(), }); @@ -46,6 +47,7 @@ export function GuestForm({ tripId, onGuestAdded }: Props) { trip: tripId, full_name: "", cpf: "", + email: "", }, }); @@ -77,7 +79,7 @@ export function GuestForm({ tripId, onGuestAdded }: Props) { const onSubmit = (data: GuestSchema) => { const payload = { ...data, - cpf: data.cpf.replace(/\D/g, ""), + cpf: data.cpf.replace(/\D/g, ""), }; addGuestMutation.mutate(payload); }; @@ -101,7 +103,7 @@ export function GuestForm({ tripId, onGuestAdded }: Props) {

Informações do Convidado

- +
Nome do convidado: )}
- -
- CPF do convidado: - { - e.target.value = normalizeCpf(e.target.value); - formOnChange(e); - }} - /> - {guestForm.formState.errors.cpf && ( -

- {guestForm.formState.errors.cpf.message} -

- )} -
- + +
+
+ CPF do convidado: + { + e.target.value = normalizeCpf(e.target.value); + formOnChange(e); + }} + /> + {guestForm.formState.errors.cpf && ( +

+ {guestForm.formState.errors.cpf.message} +

+ )} +
+
+ Email do Convidado + + {guestForm.formState.errors.email && ( +

+ {guestForm.formState.errors.email.message} +

+ )} +
+
+
-
@@ -145,4 +162,4 @@ export function GuestForm({ tripId, onGuestAdded }: Props) { )} ); -} \ No newline at end of file +} From cd386ca9188dcbd49ca75f3b7feaf3e88f73270c Mon Sep 17 00:00:00 2001 From: vini464 Date: Sun, 28 Jun 2026 21:49:43 -0300 Subject: [PATCH 2/6] feat: add guest in trips page --- frontend/components/trips/GuestForm.tsx | 154 +++++++++++++++++++ frontend/components/trips/TripsHomePage.tsx | 156 ++++++++++++-------- 2 files changed, 245 insertions(+), 65 deletions(-) create mode 100644 frontend/components/trips/GuestForm.tsx diff --git a/frontend/components/trips/GuestForm.tsx b/frontend/components/trips/GuestForm.tsx new file mode 100644 index 00000000..a91ca91a --- /dev/null +++ b/frontend/components/trips/GuestForm.tsx @@ -0,0 +1,154 @@ +import { apiFetch } from "@/lib/api"; +import { Button } from "@/lib/ui/button"; +import { FieldLabel } from "@/lib/ui/field"; +import { Input } from "@/lib/ui/input"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useMutation } from "@tanstack/react-query"; +import { useForm } from "react-hook-form"; +import z from "zod"; + +const normalizeCpf = (value: string | undefined) => { + if (!value) return ""; + return value + .replace(/[\D]/g, "") + .replace(/(\d{3})(\d)/, "$1.$2") + .replace(/(\d{3})(\d)/, "$1.$2") + .replace(/(\d{3})(\d{1,2})/, "$1-$2") + .replace(/(-\d{2})\d+?$/, "$1"); +}; + +const guestSchema = z.object({ + full_name: z.string().nonempty("Informe o nome completo"), + email: z.email("Informe um Email válidgo"), + cpf: z + .string() + .refine( + (val) => val.replace(/\D/g, "").length === 11, + "CPF deve ter exatamente 11 números.", + ), + trip: z.number(), +}); + +type GuestSchema = z.infer; + +type Props = { + tripId: number; + onGuestAdded: () => void; +}; + +export function GuestForm({ tripId, onGuestAdded }: Props) { + + const guestForm = useForm({ + resolver: zodResolver(guestSchema), + mode: "onChange", + defaultValues: { + trip: tripId, + full_name: "", + cpf: "", + email: "", + }, + }); + + const { onChange: formOnChange, ...cpfRest } = guestForm.register("cpf"); + + const addGuestMutation = useMutation({ + mutationFn: async (payload: GuestSchema) => { + return apiFetch("/trips/guest/", { + method: "POST", + body: JSON.stringify(payload), + }); + }, + onSuccess: () => { + onGuestAdded(); + return (<>Convidado Adicionado Com sucesso) + }, + onError: (error) => { + const errorData = error as { data?: { cpf?: string[] } }; + if (errorData.data?.cpf) { + guestForm.setError("cpf", { + type: "server", + message: "Esse convidado já foi adicionado para essa viagem", + }); + } + }, + }); + + const onSubmit = (data: GuestSchema) => { + const payload = { + ...data, + cpf: data.cpf.replace(/\D/g, ""), + }; + addGuestMutation.mutate(payload); + }; + + return ( + <> +
{ + guestForm.reset(); + }} + > +

+ Informações do Convidado +

+ +
+ Nome do convidado: + + {guestForm.formState.errors.full_name && ( +

+ {guestForm.formState.errors.full_name.message} +

+ )} +
+ +
+
+ CPF do convidado: + { + e.target.value = normalizeCpf(e.target.value); + formOnChange(e); + }} + /> + {guestForm.formState.errors.cpf && ( +

+ {guestForm.formState.errors.cpf.message} +

+ )} +
+
+ Email do Convidado + + {guestForm.formState.errors.email && ( +

+ {guestForm.formState.errors.email.message} +

+ )} +
+
+ +
+ + +
+
+ + ); +} diff --git a/frontend/components/trips/TripsHomePage.tsx b/frontend/components/trips/TripsHomePage.tsx index f397029b..d24fa71c 100644 --- a/frontend/components/trips/TripsHomePage.tsx +++ b/frontend/components/trips/TripsHomePage.tsx @@ -1,75 +1,84 @@ -import { useEffect, useState } from 'react' +import { useEffect, useState } from "react"; -import AppLayout from '@layout/app-layout' -import { FieldDescription } from '@ui/field' -import { Button } from '@ui/button' -import { apiFetch } from '@/lib/api' +import AppLayout from "@layout/app-layout"; +import { FieldDescription } from "@ui/field"; +import { Button } from "@ui/button"; +import { apiFetch } from "@/lib/api"; +import { GuestForm } from "./GuestForm"; +import { Dialog, DialogContent, DialogTrigger } from "@/lib/ui/dialog"; type AvailableTrip = { - id: number - trip_date: string - origin: string - destiny: string - departure_time: string - bus_brand: string - status_trip: string - available_seats: number - is_reservable: boolean - quorum_met?: boolean - reservation_deadline?: string - user_is_reserved?: boolean -} + id: number; + trip_date: string; + origin: string; + destiny: string; + departure_time: string; + bus_brand: string; + status_trip: string; + available_seats: number; + is_reservable: boolean; + quorum_met?: boolean; + reservation_deadline?: string; + user_is_reserved?: boolean; +}; export function TripsHomePage() { - const [trips, setTrips] = useState([]) - const [isLoading, setIsLoading] = useState(false) - const [error, setError] = useState(null) - const [savingTripId, setSavingTripId] = useState(null) - const [reservedTripIds, setReservedTripIds] = useState([]) + const [trips, setTrips] = useState([]); + const [isLoading, setIsLoading] = useState(false); + const [error, setError] = useState(null); + const [savingTripId, setSavingTripId] = useState(null); + const [reservedTripIds, setReservedTripIds] = useState([]); useEffect(() => { const loadTrips = async () => { - setError(null) - setIsLoading(true) + setError(null); + setIsLoading(true); try { - const data = await apiFetch('/reservations/available-trips/') - setTrips(data) + const data = await apiFetch( + "/reservations/available-trips/", + ); + setTrips(data); } catch (err) { - console.error('Erro ao carregar viagens disponíveis:', err) + console.error("Erro ao carregar viagens disponíveis:", err); - const errorData = err as { data?: { detail?: string } } | undefined - const detail = errorData?.data?.detail - const message = detail || 'Não foi possível carregar as viagens no momento.' - setError(message) + const errorData = err as { data?: { detail?: string } } | undefined; + const detail = errorData?.data?.detail; + const message = + detail || "Não foi possível carregar as viagens no momento."; + setError(message); } finally { - setIsLoading(false) + setIsLoading(false); } - } + }; - loadTrips() - }, []) + loadTrips(); + }, []); const handleReserve = async (tripId: number) => { - setSavingTripId(tripId) - setError(null) + setSavingTripId(tripId); + setError(null); try { - await apiFetch('/reservations/', { - method: 'POST', + await apiFetch("/reservations/", { + method: "POST", body: JSON.stringify({ trip: tripId }), - }) - setReservedTripIds((prev) => [...prev, tripId]) - - const data = await apiFetch('/reservations/available-trips/') - setTrips(data) + }); + setReservedTripIds((prev) => [...prev, tripId]); + + const data = await apiFetch( + "/reservations/available-trips/", + ); + setTrips(data); } catch (err) { - const errorData = err as { data?: { detail?: string } } | undefined - setError(errorData?.data?.detail || 'Não foi possível reservar esta viagem.') + const errorData = err as { data?: { detail?: string } } | undefined; + setError( + errorData?.data?.detail || "Não foi possível reservar esta viagem.", + ); } finally { - setSavingTripId(null) + setSavingTripId(null); } - } + }; return ( @@ -103,7 +112,8 @@ export function TripsHomePage() { ) : (
{trips.map((trip) => { - const isAlreadyReserved = trip.user_is_reserved || reservedTripIds.includes(trip.id) + const isAlreadyReserved = + trip.user_is_reserved || reservedTripIds.includes(trip.id); return (

- {trip.trip_date} • {trip.departure_time} • {trip.bus_brand} + {trip.trip_date} • {trip.departure_time} •{" "} + {trip.bus_brand}

Status da viagem: {trip.status_trip} @@ -131,45 +142,60 @@ export function TripsHomePage() { - +

+ + + + + { }} /> + +
- Quórum: {trip.quorum_met ? 'atingido' : 'pendente'} + Quórum: {trip.quorum_met ? "atingido" : "pendente"} {trip.reservation_deadline ? ( - Limite: {new Date(trip.reservation_deadline).toLocaleString('pt-BR')} + Limite:{" "} + {new Date(trip.reservation_deadline).toLocaleString( + "pt-BR", + )} ) : null}
- ) + ); })} )}

- As viagens exibidas respeitam o prazo de reserva e a disponibilidade de vagas no ônibus. + As viagens exibidas respeitam o prazo de reserva e a disponibilidade + de vagas no ônibus.

- ) -} \ No newline at end of file + ); +} From 09f7f0f5a0901cf6d4dbc58878c819bd76588f76 Mon Sep 17 00:00:00 2001 From: vini464 Date: Sun, 28 Jun 2026 21:56:15 -0300 Subject: [PATCH 3/6] feat: showing message "Convidado adicionado" --- frontend/components/trips/GuestForm.tsx | 1 - frontend/components/trips/TripsHomePage.tsx | 5 ++++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/frontend/components/trips/GuestForm.tsx b/frontend/components/trips/GuestForm.tsx index a91ca91a..95d129f9 100644 --- a/frontend/components/trips/GuestForm.tsx +++ b/frontend/components/trips/GuestForm.tsx @@ -60,7 +60,6 @@ export function GuestForm({ tripId, onGuestAdded }: Props) { }, onSuccess: () => { onGuestAdded(); - return (<>Convidado Adicionado Com sucesso) }, onError: (error) => { const errorData = error as { data?: { cpf?: string[] } }; diff --git a/frontend/components/trips/TripsHomePage.tsx b/frontend/components/trips/TripsHomePage.tsx index d24fa71c..c856394f 100644 --- a/frontend/components/trips/TripsHomePage.tsx +++ b/frontend/components/trips/TripsHomePage.tsx @@ -6,6 +6,7 @@ import { Button } from "@ui/button"; import { apiFetch } from "@/lib/api"; import { GuestForm } from "./GuestForm"; import { Dialog, DialogContent, DialogTrigger } from "@/lib/ui/dialog"; +import { Textarea } from "@/lib/ui/textarea"; type AvailableTrip = { id: number; @@ -25,6 +26,7 @@ type AvailableTrip = { export function TripsHomePage() { const [trips, setTrips] = useState([]); const [isLoading, setIsLoading] = useState(false); + const [addedGuest, setAddedGuest] = useState(false); const [error, setError] = useState(null); const [savingTripId, setSavingTripId] = useState(null); const [reservedTripIds, setReservedTripIds] = useState([]); @@ -167,7 +169,8 @@ export function TripsHomePage() { - { }} /> +{!addedGuest && ( {setAddedGuest(true)}} />)} +{addedGuest && ()} From 4aeb20b37f1eb503511003f95ed6b651999f45d7 Mon Sep 17 00:00:00 2001 From: vini464 Date: Sun, 28 Jun 2026 22:00:31 -0300 Subject: [PATCH 4/6] fix: replace add guest form in user current trip --- .../current-trip/CurrentTripPage.tsx | 19 +- .../components/current-trip/GuestForm.tsx | 165 ------------------ frontend/components/trips/TripsHomePage.tsx | 2 +- .../components/{trips => utils}/GuestForm.tsx | 0 4 files changed, 14 insertions(+), 172 deletions(-) delete mode 100644 frontend/components/current-trip/GuestForm.tsx rename frontend/components/{trips => utils}/GuestForm.tsx (100%) diff --git a/frontend/components/current-trip/CurrentTripPage.tsx b/frontend/components/current-trip/CurrentTripPage.tsx index 097d0950..1865ca84 100644 --- a/frontend/components/current-trip/CurrentTripPage.tsx +++ b/frontend/components/current-trip/CurrentTripPage.tsx @@ -15,8 +15,9 @@ import { Separator } from "@/lib/ui/separator"; import { apiFetch } from "@/lib/api"; import { formatTripDate } from "@/features/user-home/config"; import PassengerQRCode from "@/lib/ui/qr-code"; -import { GuestForm } from "./GuestForm"; -import { useAuthStore } from "@/features/auth/store/auth-store"; +import { GuestForm } from "@/components/utils/GuestForm"; +import { Dialog, DialogContent, DialogTrigger } from "@/lib/ui/dialog"; +import { Textarea } from "@/lib/ui/textarea"; type PassengerGuest = { id: string; @@ -64,10 +65,10 @@ function getErrorMessage(detail?: string) { export function CurrentTripPage() { const [trip, setTrip] = useState(null); const [isLoading, setIsLoading] = useState(false); + const [addedGuest, setAddedGuest] = useState(false); const [error, setError] = useState(null); const showMinutesCard = trip !== null && trip.minutes_remaining !== null; - const user = useAuthStore((state) => state.user); const isTripInProgress = trip?.status_trip?.toLowerCase() === "em andamento"; const percentage = Math.min( 100, @@ -284,9 +285,15 @@ export function CurrentTripPage() { - {!isTripInProgress && user?.profile_type === "CIVIL-SERVANT" && ( - setRefreshKey((old) => old + 1)} /> - )} + + + + + +{!addedGuest && ( {setAddedGuest(true)}} />)} +{addedGuest && ()} + + ) : (
diff --git a/frontend/components/current-trip/GuestForm.tsx b/frontend/components/current-trip/GuestForm.tsx deleted file mode 100644 index ff5a74f5..00000000 --- a/frontend/components/current-trip/GuestForm.tsx +++ /dev/null @@ -1,165 +0,0 @@ -import { apiFetch } from "@/lib/api"; -import { Button } from "@/lib/ui/button"; -import { FieldLabel } from "@/lib/ui/field"; -import { Input } from "@/lib/ui/input"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { useMutation } from "@tanstack/react-query"; -import { useState } from "react"; -import { useForm } from "react-hook-form"; -import z from "zod"; - -const normalizeCpf = (value: string | undefined) => { - if (!value) return ""; - return value - .replace(/[\D]/g, "") - .replace(/(\d{3})(\d)/, "$1.$2") - .replace(/(\d{3})(\d)/, "$1.$2") - .replace(/(\d{3})(\d{1,2})/, "$1-$2") - .replace(/(-\d{2})\d+?$/, "$1"); -}; - -const guestSchema = z.object({ - full_name: z.string().nonempty("Informe o nome completo"), - email: z.email("Informe um Email válidgo"), - cpf: z - .string() - .refine( - (val) => val.replace(/\D/g, "").length === 11, - "CPF deve ter exatamente 11 números.", - ), - trip: z.number(), -}); - -type GuestSchema = z.infer; - -type Props = { - tripId: number; - onGuestAdded: () => void; -}; - -export function GuestForm({ tripId, onGuestAdded }: Props) { - const [isAdding, setIsAdding] = useState(false); - - const guestForm = useForm({ - resolver: zodResolver(guestSchema), - mode: "onChange", - defaultValues: { - trip: tripId, - full_name: "", - cpf: "", - email: "", - }, - }); - - const { onChange: formOnChange, ...cpfRest } = guestForm.register("cpf"); - - const addGuestMutation = useMutation({ - mutationFn: async (payload: GuestSchema) => { - return apiFetch("/trips/guest/", { - method: "POST", - body: JSON.stringify(payload), - }); - }, - onSuccess: () => { - guestForm.reset(); - setIsAdding(false); - onGuestAdded(); - }, - onError: (error) => { - const errorData = error as { data?: { cpf?: string[] } }; - if (errorData.data?.cpf) { - guestForm.setError("cpf", { - type: "server", - message: "Esse convidado já foi adicionado para essa viagem", - }); - } - }, - }); - - const onSubmit = (data: GuestSchema) => { - const payload = { - ...data, - cpf: data.cpf.replace(/\D/g, ""), - }; - addGuestMutation.mutate(payload); - }; - - return ( - <> - {!isAdding && ( - - )} - {isAdding && ( -
{ - setIsAdding(false); - guestForm.reset(); - }} - > -

- Informações do Convidado -

- -
- Nome do convidado: - - {guestForm.formState.errors.full_name && ( -

- {guestForm.formState.errors.full_name.message} -

- )} -
- -
-
- CPF do convidado: - { - e.target.value = normalizeCpf(e.target.value); - formOnChange(e); - }} - /> - {guestForm.formState.errors.cpf && ( -

- {guestForm.formState.errors.cpf.message} -

- )} -
-
- Email do Convidado - - {guestForm.formState.errors.email && ( -

- {guestForm.formState.errors.email.message} -

- )} -
-
- -
- - -
-
- )} - - ); -} diff --git a/frontend/components/trips/TripsHomePage.tsx b/frontend/components/trips/TripsHomePage.tsx index c856394f..95a3227d 100644 --- a/frontend/components/trips/TripsHomePage.tsx +++ b/frontend/components/trips/TripsHomePage.tsx @@ -4,7 +4,7 @@ import AppLayout from "@layout/app-layout"; import { FieldDescription } from "@ui/field"; import { Button } from "@ui/button"; import { apiFetch } from "@/lib/api"; -import { GuestForm } from "./GuestForm"; +import { GuestForm } from "@/components/utils/GuestForm"; import { Dialog, DialogContent, DialogTrigger } from "@/lib/ui/dialog"; import { Textarea } from "@/lib/ui/textarea"; diff --git a/frontend/components/trips/GuestForm.tsx b/frontend/components/utils/GuestForm.tsx similarity index 100% rename from frontend/components/trips/GuestForm.tsx rename to frontend/components/utils/GuestForm.tsx From c27989d14b1c4fd4eb76ac39ae7b70cc240dd67e Mon Sep 17 00:00:00 2001 From: vini464 Date: Sun, 28 Jun 2026 22:06:27 -0300 Subject: [PATCH 5/6] fix: setting addedguest to false when click in dialog button --- frontend/components/current-trip/CurrentTripPage.tsx | 2 +- frontend/components/trips/TripsHomePage.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/components/current-trip/CurrentTripPage.tsx b/frontend/components/current-trip/CurrentTripPage.tsx index 1865ca84..b3ca837f 100644 --- a/frontend/components/current-trip/CurrentTripPage.tsx +++ b/frontend/components/current-trip/CurrentTripPage.tsx @@ -287,7 +287,7 @@ export function CurrentTripPage() { - + {!addedGuest && ( {setAddedGuest(true)}} />)} diff --git a/frontend/components/trips/TripsHomePage.tsx b/frontend/components/trips/TripsHomePage.tsx index 95a3227d..9a16ff9d 100644 --- a/frontend/components/trips/TripsHomePage.tsx +++ b/frontend/components/trips/TripsHomePage.tsx @@ -166,7 +166,7 @@ export function TripsHomePage() { - + {!addedGuest && ( {setAddedGuest(true)}} />)} From 46da09691225925134f6af144790bab7825b20d3 Mon Sep 17 00:00:00 2001 From: vini464 Date: Sun, 28 Jun 2026 22:18:24 -0300 Subject: [PATCH 6/6] feat: saving guest passenger with email --- .../migrations/0011_guestpassenger_email.py | 18 ++++++++++++++++++ api/apps/trips/models.py | 1 + api/apps/trips/serializers.py | 2 +- api/apps/trips/views.py | 9 +++++++++ 4 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 api/apps/trips/migrations/0011_guestpassenger_email.py diff --git a/api/apps/trips/migrations/0011_guestpassenger_email.py b/api/apps/trips/migrations/0011_guestpassenger_email.py new file mode 100644 index 00000000..0ff9b414 --- /dev/null +++ b/api/apps/trips/migrations/0011_guestpassenger_email.py @@ -0,0 +1,18 @@ +# Generated by Django 6.0.6 on 2026-06-29 01:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("trips", "0010_merge_20260628_1708"), + ] + + operations = [ + migrations.AddField( + model_name="guestpassenger", + name="email", + field=models.EmailField(max_length=254, null=True), + ), + ] diff --git a/api/apps/trips/models.py b/api/apps/trips/models.py index bcfb9ba8..9cdb2dd5 100644 --- a/api/apps/trips/models.py +++ b/api/apps/trips/models.py @@ -236,6 +236,7 @@ def create_passenger(self, cpf, trip, **extra_fields): class GuestPassenger(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) cpf = models.CharField(max_length=11) + email = models.EmailField(null=True) trip = models.ForeignKey(to=Trip, on_delete=models.CASCADE) recorded_by = models.ForeignKey( to=CivilServantProfile, on_delete=models.SET_NULL, null=True diff --git a/api/apps/trips/serializers.py b/api/apps/trips/serializers.py index 4d9efeda..86ae3cdb 100644 --- a/api/apps/trips/serializers.py +++ b/api/apps/trips/serializers.py @@ -551,4 +551,4 @@ class GuestPassengerSerializer(serializers.ModelSerializer): class Meta: model = GuestPassenger - fields = ("id", "cpf", "full_name") + fields = ("id", "cpf", "full_name", "email") diff --git a/api/apps/trips/views.py b/api/apps/trips/views.py index 5cc889fe..e9811995 100644 --- a/api/apps/trips/views.py +++ b/api/apps/trips/views.py @@ -589,6 +589,8 @@ class GuestPassengerView(APIView): def post(self, request): trip_id = request.data.get("trip") cpf = request.data.get("cpf") + email = request.data.get("email") + if not trip_id: return Response( {"trip": ["This field is required."]}, @@ -601,9 +603,16 @@ def post(self, request): status=status.HTTP_400_BAD_REQUEST, ) + if not email: + return Response( + {"email": ["This field is required."]}, + status=status.HTTP_400_BAD_REQUEST, + ) + passenger = GuestPassenger.objects.create( cpf=cpf, trip_id=trip_id, + email=email, recorded_by=request.user.civil_servant_profile, full_name=request.data.get("full_name"), )