create sender fix

This commit is contained in:
2025-05-22 13:52:02 +03:00
parent 4182708db7
commit b0aef18c38
6 changed files with 115 additions and 57 deletions

View File

@@ -105,7 +105,7 @@ class CreateRouteSerializer(serializers.ModelSerializer):
arrival = serializers.DateTimeField(source='arrival_DT') arrival = serializers.DateTimeField(source='arrival_DT')
transport = serializers.ChoiceField(choices=type_transport_choices, source='type_transport') transport = serializers.ChoiceField(choices=type_transport_choices, source='type_transport')
email_notification = serializers.BooleanField(source='receive_msg_by_email') email_notification = serializers.BooleanField(source='receive_msg_by_email')
contact_number = serializers.CharField(write_only=True) phone_number = serializers.CharField(write_only=True)
owner_type = serializers.ChoiceField(choices=[('sender', 'Отправитель'), ('deliverer', 'Перевозчик')]) owner_type = serializers.ChoiceField(choices=[('sender', 'Отправитель'), ('deliverer', 'Перевозчик')])
class Meta: class Meta:
@@ -156,14 +156,14 @@ class CreateRouteSerializer(serializers.ModelSerializer):
# проверяем существование городов в указанных странах # проверяем существование городов в указанных странах
try: try:
City.objects.get(name=data['city_from'], country=country_from) city_from = City.objects.get(name=data['city_from'], country=country_from)
except City.DoesNotExist: except City.DoesNotExist:
raise serializers.ValidationError({ raise serializers.ValidationError({
"city_from": f"Город '{data['city_from']}' не найден в стране {country_from}" "city_from": f"Город '{data['city_from']}' не найден в стране {country_from}"
}) })
try: try:
City.objects.get(name=data['city_to'], country=country_to) city_to = City.objects.get(name=data['city_to'], country=country_to)
except City.DoesNotExist: except City.DoesNotExist:
raise serializers.ValidationError({ raise serializers.ValidationError({
"city_to": f"Город '{data['city_to']}' не найден в стране {country_to}" "city_to": f"Город '{data['city_to']}' не найден в стране {country_to}"
@@ -172,33 +172,36 @@ class CreateRouteSerializer(serializers.ModelSerializer):
return data return data
def create(self, validated_data): def create(self, validated_data):
# получаем города и страны try:
country_from = Country.objects.get(international_name=validated_data.pop('country_from')) # получаем города и страны
country_to = Country.objects.get(international_name=validated_data.pop('country_to')) country_from = Country.objects.get(international_name=validated_data.pop('country_from'))
country_to = Country.objects.get(international_name=validated_data.pop('country_to'))
from_city = City.objects.get(name=validated_data.pop('city_from'), country=country_from) from_city = City.objects.get(name=validated_data.pop('city_from'), country=country_from)
to_city = City.objects.get(name=validated_data.pop('city_to'), country=country_to) to_city = City.objects.get(name=validated_data.pop('city_to'), country=country_to)
# обновляем номер телефона в профиле пользователя # обновляем номер телефона в профиле пользователя
phone_number = validated_data.pop('phone_number') phone_number = validated_data.pop('phone_number') # Удаляем из validated_data
user_profile = get_object_or_404(UserProfile, user=self.context['request'].user) user_profile = get_object_or_404(UserProfile, user=self.context['request'].user)
# проверяем, не используется ли этот номер другим пользователем # проверяем, не используется ли этот номер другим пользователем
if UserProfile.objects.filter(phone_number=phone_number).exclude(user=self.context['request'].user).exists(): if UserProfile.objects.filter(phone_number=phone_number).exclude(user=self.context['request'].user).exists():
raise serializers.ValidationError({ raise serializers.ValidationError({
"phone_number": "Этот номер телефона уже используется другим пользователем" "phone_number": "Этот номер телефона уже используется другим пользователем"
}) })
user_profile.phone_number = phone_number user_profile.phone_number = phone_number
user_profile.save() user_profile.save()
# создаем маршрут # создаем маршрут
route = Route.objects.create( route = Route.objects.create(
from_city=from_city, from_city=from_city,
to_city=to_city, to_city=to_city,
owner=self.context['request'].user, owner=self.context['request'].user,
**validated_data # owner_type приходит с фронта **validated_data
) )
return route return route
except Exception as e:
raise

View File

@@ -97,10 +97,18 @@ class AccountActionsView(ViewSet):
@action(detail=False, methods=['post']) @action(detail=False, methods=['post'])
@handle_exceptions @handle_exceptions
def create_route(self, request): def create_route(self, request):
serializer = CreateRouteSerializer(data=request.data) print("[DEBUG] Входящие данные в create_route view:", request.data)
serializer.is_valid(raise_exception=True) try:
serializer.save() serializer = CreateRouteSerializer(data=request.data, context={'request': request})
return Response(serializer.data, status=status.HTTP_201_CREATED) if not serializer.is_valid():
print("[DEBUG] Ошибки валидации:", serializer.errors)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
route = serializer.save()
print("[DEBUG] Маршрут успешно создан в view:", route.id)
return Response(serializer.data, status=status.HTTP_201_CREATED)
except Exception as e:
print("[DEBUG] Необработанная ошибка в create_route:", str(e))
raise
class CityView(ViewSet): class CityView(ViewSet):

View File

@@ -47,12 +47,13 @@ const validationRules = {
minLength: 11, minLength: 11,
pattern: /^\+?[0-9]{11,}$/, pattern: /^\+?[0-9]{11,}$/,
}, },
comment: { required: false, minLength: 10 }, comment: { required: false },
email_notification: { required: false }, email_notification: { required: false },
} }
const SenderPage = () => { const SenderPage = () => {
const { user, setUser } = useUserStore() const { user, setUser } = useUserStore()
const today = formatDateToHTML(new Date()) const today = formatDateToHTML(new Date())
const initialValues: SenderPageProps = { const initialValues: SenderPageProps = {
@@ -73,38 +74,75 @@ const SenderPage = () => {
const cargoOptions: SelectOption[] = cargo_types.map((type, index) => ({ const cargoOptions: SelectOption[] = cargo_types.map((type, index) => ({
id: index + 1, id: index + 1,
label: cargo_type_translations[type],
value: type, value: type,
label: cargo_type_translations[type],
})) }))
const transportOptions: SelectOption[] = transport_types.map((type, index) => ({ const transportOptions: SelectOption[] = transport_types.map((type, index) => ({
id: index + 1, id: index + 1,
label: transport_translations[type],
value: type, value: type,
label: transport_translations[type],
})) }))
const { values, handleChange, handleSubmit } = useForm<SenderPageProps>( const { values, handleChange, handleSubmit, resetField } = useForm<SenderPageProps>(
initialValues, initialValues,
validationRules, validationRules,
async values => { async values => {
try { try {
// находим выбранные опции
const selectedTransport = transportOptions.find(
opt => opt.id.toString() === values.transport
)
const selectedCargoType = cargoOptions.find(opt => opt.id.toString() === values.cargo_type)
if (!selectedTransport || !selectedCargoType) {
throw new Error('Некорректный тип транспорта или груза')
}
// подготавливаем данные для отправки
const requestData = {
...values,
owner_type: 'sender',
transport: selectedTransport.value,
cargo_type: selectedCargoType.value,
phone_number: values.phone_number,
}
const response = await fetch('/api/account/sender', { const response = await fetch('/api/account/sender', {
method: 'PATCH', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}, },
body: JSON.stringify(values), body: JSON.stringify(requestData),
}) })
if (!response.ok) { if (!response.ok) {
const error = await response.json() const error = await response.json()
throw new Error(error.error || 'Ошибка при обновлении данных') console.error('Ошибка от сервера:', error)
throw new Error(error.error || 'Ошибка при создании маршрута')
} }
const result = await response.json() // Обновляем номер телефона в сторе, если он изменился
setUser(result.user) if (user && user.phone_number !== values.phone_number) {
showToast({ type: 'success', message: 'Данные успешно обновлены!' }) setUser({
...user,
phone_number: values.phone_number,
})
}
showToast({
type: 'success',
message: 'Маршрут успешно создан!',
})
// сбрасываем все поля формы кроме телефона
Object.keys(initialValues).forEach(field => {
if (field !== 'phone_number') {
resetField(field)
}
})
} catch (error) { } catch (error) {
console.error('Ошибка:', error)
showToast({ showToast({
type: 'error', type: 'error',
message: error instanceof Error ? error.message : 'Ой, что то пошло не так..', message: error instanceof Error ? error.message : 'Ой, что то пошло не так..',

View File

@@ -34,18 +34,18 @@ export async function POST(req: NextRequest) {
Authorization: `Bearer ${session.accessToken}`, Authorization: `Bearer ${session.accessToken}`,
}, },
body: JSON.stringify({ body: JSON.stringify({
owner_type: 'sender', owner_type: data.owner_type,
transport, transport: data.transport,
country_from, country_from: data.country_from,
city_from, city_from: data.city_from,
country_to, country_to: data.country_to,
city_to, city_to: data.city_to,
cargo_type, cargo_type: data.cargo_type,
departure, departure: data.departure,
arrival, arrival: data.arrival,
phone_number, phone_number: data.phone_number,
comment, comment: data.comment || '',
email_notification, email_notification: data.email_notification,
}), }),
}) })

View File

@@ -68,6 +68,14 @@ export function useForm<T extends Record<string, FormValue>>(
phone_number: 'Номер телефона', phone_number: 'Номер телефона',
password: 'Пароль', password: 'Пароль',
privacy_policy: 'Политика конфиденциальности', privacy_policy: 'Политика конфиденциальности',
arrival: 'Дата прибытия',
departure: 'Дата отправления',
cargo_type: 'Тип груза',
city_from: 'Город отправления',
country_to: 'Страна назначения',
city_to: 'Город назначения',
country_from_id: 'Страна отправления',
country_to_id: 'Страна отправления',
} }
const validate = () => { const validate = () => {

View File

@@ -171,6 +171,7 @@ export interface Route {
export interface SelectOption { export interface SelectOption {
id: number id: number
label: string label: string
value: string | CargoType | TransportType
} }
export interface MultiSelectProps { export interface MultiSelectProps {