fix: sửa lại cho phép chỉnh sửa thời gian bắt đầu và kết thúc của điểm xuất phát và điểm kết thúc
This commit is contained in:
Vendored
+4
-2
@@ -419,7 +419,7 @@ let TourController = class TourController {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
async updateTourStartPoint(tourId, body, req) {
|
async updateTourStartPoint(tourId, body, req) {
|
||||||
const { latitude, longitude, name } = body;
|
const { latitude, longitude, name, plannedEnd } = body;
|
||||||
console.log(`[USER ACTION] User ${req.user.id} set START point for Tour ${tourId}: "${name}" at [${latitude}, ${longitude}]`);
|
console.log(`[USER ACTION] User ${req.user.id} set START point for Tour ${tourId}: "${name}" at [${latitude}, ${longitude}]`);
|
||||||
await this.prisma.location.deleteMany({
|
await this.prisma.location.deleteMany({
|
||||||
where: {
|
where: {
|
||||||
@@ -441,6 +441,7 @@ let TourController = class TourController {
|
|||||||
type: 'MOVE',
|
type: 'MOVE',
|
||||||
legId: firstLeg.id,
|
legId: firstLeg.id,
|
||||||
plannedStart: new Date(0),
|
plannedStart: new Date(0),
|
||||||
|
plannedEnd: plannedEnd ? new Date(plannedEnd) : null,
|
||||||
}
|
}
|
||||||
}).then(async (loc) => {
|
}).then(async (loc) => {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
@@ -452,7 +453,7 @@ let TourController = class TourController {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
async updateTourEndPoint(tourId, body, req) {
|
async updateTourEndPoint(tourId, body, req) {
|
||||||
const { latitude, longitude, name } = body;
|
const { latitude, longitude, name, plannedStart } = body;
|
||||||
console.log(`[USER ACTION] User ${req.user.id} set END point for Tour ${tourId}: "${name}" at [${latitude}, ${longitude}]`);
|
console.log(`[USER ACTION] User ${req.user.id} set END point for Tour ${tourId}: "${name}" at [${latitude}, ${longitude}]`);
|
||||||
await this.prisma.location.deleteMany({
|
await this.prisma.location.deleteMany({
|
||||||
where: {
|
where: {
|
||||||
@@ -473,6 +474,7 @@ let TourController = class TourController {
|
|||||||
longitude,
|
longitude,
|
||||||
type: 'MOVE',
|
type: 'MOVE',
|
||||||
legId: lastLeg.id,
|
legId: lastLeg.id,
|
||||||
|
plannedStart: plannedStart ? new Date(plannedStart) : null,
|
||||||
plannedEnd: new Date(0),
|
plannedEnd: new Date(0),
|
||||||
}
|
}
|
||||||
}).then(async (loc) => {
|
}).then(async (loc) => {
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+4
-2
@@ -396,7 +396,7 @@ class TourController {
|
|||||||
@UseGuards(JwtAuthGuard, TourRoleGuard)
|
@UseGuards(JwtAuthGuard, TourRoleGuard)
|
||||||
@Post(':tourId/start-point')
|
@Post(':tourId/start-point')
|
||||||
async updateTourStartPoint(@Param('tourId', ParseUUIDPipe) tourId: string, @Body() body: any, @Req() req: any) {
|
async updateTourStartPoint(@Param('tourId', ParseUUIDPipe) tourId: string, @Body() body: any, @Req() req: any) {
|
||||||
const { latitude, longitude, name } = body;
|
const { latitude, longitude, name, plannedEnd } = body;
|
||||||
|
|
||||||
console.log(`[USER ACTION] User ${req.user.id} set START point for Tour ${tourId}: "${name}" at [${latitude}, ${longitude}]`);
|
console.log(`[USER ACTION] User ${req.user.id} set START point for Tour ${tourId}: "${name}" at [${latitude}, ${longitude}]`);
|
||||||
|
|
||||||
@@ -426,6 +426,7 @@ class TourController {
|
|||||||
type: 'MOVE',
|
type: 'MOVE',
|
||||||
legId: firstLeg.id,
|
legId: firstLeg.id,
|
||||||
plannedStart: new Date(0),
|
plannedStart: new Date(0),
|
||||||
|
plannedEnd: plannedEnd ? new Date(plannedEnd) : null,
|
||||||
}
|
}
|
||||||
}).then(async (loc) => {
|
}).then(async (loc) => {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
@@ -441,7 +442,7 @@ class TourController {
|
|||||||
@UseGuards(JwtAuthGuard, TourRoleGuard)
|
@UseGuards(JwtAuthGuard, TourRoleGuard)
|
||||||
@Post(':tourId/end-point')
|
@Post(':tourId/end-point')
|
||||||
async updateTourEndPoint(@Param('tourId', ParseUUIDPipe) tourId: string, @Body() body: any, @Req() req: any) {
|
async updateTourEndPoint(@Param('tourId', ParseUUIDPipe) tourId: string, @Body() body: any, @Req() req: any) {
|
||||||
const { latitude, longitude, name } = body;
|
const { latitude, longitude, name, plannedStart } = body;
|
||||||
|
|
||||||
console.log(`[USER ACTION] User ${req.user.id} set END point for Tour ${tourId}: "${name}" at [${latitude}, ${longitude}]`);
|
console.log(`[USER ACTION] User ${req.user.id} set END point for Tour ${tourId}: "${name}" at [${latitude}, ${longitude}]`);
|
||||||
|
|
||||||
@@ -468,6 +469,7 @@ class TourController {
|
|||||||
longitude,
|
longitude,
|
||||||
type: 'MOVE',
|
type: 'MOVE',
|
||||||
legId: lastLeg.id,
|
legId: lastLeg.id,
|
||||||
|
plannedStart: plannedStart ? new Date(plannedStart) : null,
|
||||||
plannedEnd: new Date(0), // Đánh dấu đây là điểm kết thúc đặc biệt
|
plannedEnd: new Date(0), // Đánh dấu đây là điểm kết thúc đặc biệt
|
||||||
}
|
}
|
||||||
}).then(async (loc) => {
|
}).then(async (loc) => {
|
||||||
|
|||||||
@@ -108,7 +108,9 @@ export const AddLocationModal = ({ isOpen, onClose, tourId, initialLegId, editin
|
|||||||
expenseDescription: expense?.description || '',
|
expenseDescription: expense?.description || '',
|
||||||
expenseNote: expense?.note || '',
|
expenseNote: expense?.note || '',
|
||||||
paidById: expense?.paidById || '',
|
paidById: expense?.paidById || '',
|
||||||
plannedStart: editingLocation.plannedStart ? editingLocation.plannedStart.slice(0, 16) : '',
|
plannedStart: isStartPoint
|
||||||
|
? (editingLocation.plannedEnd ? editingLocation.plannedEnd.slice(0, 16) : '')
|
||||||
|
: (editingLocation.plannedStart ? editingLocation.plannedStart.slice(0, 16) : ''),
|
||||||
plannedEnd: editingLocation.plannedEnd ? editingLocation.plannedEnd.slice(0, 16) : ''
|
plannedEnd: editingLocation.plannedEnd ? editingLocation.plannedEnd.slice(0, 16) : ''
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -291,12 +293,14 @@ export const AddLocationModal = ({ isOpen, onClose, tourId, initialLegId, editin
|
|||||||
name: formData.name || "Điểm xuất phát",
|
name: formData.name || "Điểm xuất phát",
|
||||||
latitude: parseFloat(formData.latitude as any),
|
latitude: parseFloat(formData.latitude as any),
|
||||||
longitude: parseFloat(formData.longitude as any),
|
longitude: parseFloat(formData.longitude as any),
|
||||||
|
plannedEnd: formData.plannedStart,
|
||||||
});
|
});
|
||||||
} else if (isEndPoint) {
|
} else if (isEndPoint) {
|
||||||
await updateTourEndPoint(tourId, {
|
await updateTourEndPoint(tourId, {
|
||||||
name: formData.name || "Điểm kết thúc",
|
name: formData.name || "Điểm kết thúc",
|
||||||
latitude: parseFloat(formData.latitude as any),
|
latitude: parseFloat(formData.latitude as any),
|
||||||
longitude: parseFloat(formData.longitude as any),
|
longitude: parseFloat(formData.longitude as any),
|
||||||
|
plannedStart: formData.plannedStart,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const payload: any = {
|
const payload: any = {
|
||||||
|
|||||||
@@ -352,16 +352,19 @@ export const ItineraryTimeline = ({
|
|||||||
? calculateDistance(prevLocation.latitude, prevLocation.longitude, location.latitude, location.longitude)
|
? calculateDistance(prevLocation.latitude, prevLocation.longitude, location.latitude, location.longitude)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
const dwellMinutes = (location.plannedStart && location.plannedEnd)
|
|
||||||
? differenceInMinutes(parseISO(location.plannedEnd), parseISO(location.plannedStart))
|
|
||||||
: null;
|
|
||||||
|
|
||||||
const locationExpense = leg.expenses?.find((e: any) => e.locationId === location.id);
|
const locationExpense = leg.expenses?.find((e: any) => e.locationId === location.id);
|
||||||
|
|
||||||
// Nhận diện điểm mốc dựa trên timestamp đặc biệt (0) thay vì chỉ số mảng
|
// Nhận diện điểm mốc dựa trên timestamp đặc biệt (0) thay vì chỉ số mảng
|
||||||
const isStartPoint = location.plannedStart && new Date(location.plannedStart).getTime() === 0;
|
const isStartPoint = location.plannedStart && new Date(location.plannedStart).getTime() === 0;
|
||||||
const isEndPoint = location.plannedEnd && new Date(location.plannedEnd).getTime() === 0;
|
const isEndPoint = location.plannedEnd && new Date(location.plannedEnd).getTime() === 0;
|
||||||
|
|
||||||
|
const plannedTimeStr = isStartPoint ? location.plannedEnd : location.plannedStart;
|
||||||
|
const hasValidPlannedTime = plannedTimeStr && new Date(plannedTimeStr).getTime() !== 0;
|
||||||
|
|
||||||
|
const dwellMinutes = (location.plannedStart && location.plannedEnd && !isStartPoint && !isEndPoint)
|
||||||
|
? differenceInMinutes(parseISO(location.plannedEnd), parseISO(location.plannedStart))
|
||||||
|
: null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={location.id}>
|
<div key={location.id}>
|
||||||
<div className="relative flex group mb-6">
|
<div className="relative flex group mb-6">
|
||||||
@@ -453,7 +456,7 @@ export const ItineraryTimeline = ({
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center text-sm font-black text-blue-600">
|
<div className="flex items-center text-sm font-black text-blue-600">
|
||||||
<Clock className="w-3 h-3 mr-1" />
|
<Clock className="w-3 h-3 mr-1" />
|
||||||
{location.plannedStart ? format(parseISO(location.plannedStart), 'HH:mm') : '--:--'}
|
{hasValidPlannedTime ? format(parseISO(plannedTimeStr), 'HH:mm') : '--:--'}
|
||||||
</div>
|
</div>
|
||||||
{location.status === 'COMPLETED' && location.actualStart && (
|
{location.status === 'COMPLETED' && location.actualStart && (
|
||||||
<div className="text-[10px] text-gray-400 mt-1 italic">
|
<div className="text-[10px] text-gray-400 mt-1 italic">
|
||||||
@@ -474,7 +477,7 @@ export const ItineraryTimeline = ({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Logic tính toán độ lệch thời gian */}
|
{/* Logic tính toán độ lệch thời gian */}
|
||||||
<TimeVariance planned={location.plannedStart || ''} actual={location.actualStart || null} />
|
<TimeVariance planned={hasValidPlannedTime ? plannedTimeStr : ''} actual={location.actualStart || null} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user