|
|
|
|
@ -6,32 +6,51 @@ import SearchForm from '@/components/SearchForm';
|
|
|
|
|
import useReportStore from '@/stores/Report';
|
|
|
|
|
import { useTranslation } from 'react-i18next'
|
|
|
|
|
import { usingStorage } from '@/hooks/usingStorage';
|
|
|
|
|
import { VSTag } from '@/components/Data';
|
|
|
|
|
import { DATE_FORMAT } from '@/config';
|
|
|
|
|
|
|
|
|
|
function Index() {
|
|
|
|
|
const { t } = useTranslation();
|
|
|
|
|
|
|
|
|
|
const {travelAgencyId, } = usingStorage();
|
|
|
|
|
const [loading, vendorScoresData, getHWVendorScores] = useReportStore((state) => [state.loading, state.vendorScoresData, state.getHWVendorScores]);
|
|
|
|
|
const [productScoresData, getHWProductScores] = useReportStore((state) => [state.productScoresData, state.getHWProductScores]);
|
|
|
|
|
const [commendScoresData, getHWCommendScores] = useReportStore((state) => [state.commendScoresData, state.getHWCommendScores]);
|
|
|
|
|
const [loading, setLoading, reset] = useReportStore((state) => [state.loading, state.setLoading, state.reset]);
|
|
|
|
|
const [vendorScoresData, vendorScoresDataDiff, getHWVendorScores] = useReportStore((state) => [state.vendorScoresData, state.vendorScoresDataDiff, state.getHWVendorScores]);
|
|
|
|
|
const [productScoresData, productScoresDataDiff, getHWProductScores] = useReportStore((state) => [state.productScoresData, state.productScoresDataDiff, state.getHWProductScores]);
|
|
|
|
|
const [commendScoresData, commendScoresDataDiff, getHWCommendScores] = useReportStore((state) => [state.commendScoresData, state.commendScoresDataDiff, state.getHWCommendScores]);
|
|
|
|
|
|
|
|
|
|
const evaluationScores = vendorScoresData.EvaluationScores ? vendorScoresData.EvaluationScores[0] : [];
|
|
|
|
|
const evaluationScores = vendorScoresData.EvaluationScores ? vendorScoresData.EvaluationScores[0] : {};
|
|
|
|
|
const evaluationScoresDiff = vendorScoresDataDiff.EvaluationScores ? vendorScoresDataDiff.EvaluationScores[0] : {};
|
|
|
|
|
const primaryData = vendorScoresData.EvaluationScores
|
|
|
|
|
? [comm.pick(vendorScoresData.EvaluationScores[0], ['Groups', 'PersonNum', 'AmountUSD', 'EvaluationScore', 'TPReviews', 'TPReviewRate', 'Complaints', 'ComplaintRate'])]
|
|
|
|
|
: [];
|
|
|
|
|
let MonthlyData = vendorScoresData.MonthlyData || [];
|
|
|
|
|
if (vendorScoresData.EvaluationScores && !comm.isEmpty(vendorScoresDataDiff)) {
|
|
|
|
|
primaryData[0].diff = vendorScoresDataDiff.EvaluationScores
|
|
|
|
|
? comm.pick(vendorScoresDataDiff.EvaluationScores[0], ['Groups', 'PersonNum', 'AmountUSD', 'EvaluationScore', 'TPReviews', 'TPReviewRate', 'Complaints', 'ComplaintRate'])
|
|
|
|
|
: {};
|
|
|
|
|
MonthlyData = MonthlyData.map((row, ri) => ({...row, diff: vendorScoresDataDiff.MonthlyData[ri]}))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const guideData = (productScoresData?.GuideScores || []).reduce((a, row) => ({...a, [row.key]: row}), {});
|
|
|
|
|
const guideDataDiff = (productScoresDataDiff?.GuideScores || []).reduce((a, row) => ({...a, [row.key]: row}), {});
|
|
|
|
|
if (productScoresData.GuideScores && !comm.isEmpty(productScoresDataDiff)) {
|
|
|
|
|
Object.keys(guideData).forEach(key => {
|
|
|
|
|
guideData[key].diff = guideDataDiff[key];
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const evaluationScoresData = [
|
|
|
|
|
{ category: 'DMC Services', item: 'Guide', value: evaluationScores.FRTGuide, note: evaluationScores.FRTText },
|
|
|
|
|
{ category: 'DMC Services', item: 'Driver & Vehicle', value: evaluationScores.FRTGriver },
|
|
|
|
|
{ category: 'DMC Services', item: 'Food Arrangement', value: evaluationScores.FRTMeal },
|
|
|
|
|
{ category: 'DMC Services', item: 'Activity', value: evaluationScores.FRTProduct },
|
|
|
|
|
{ category: 'Itinerary Arrangements', item: 'Hotel', value: evaluationScores.FRTHotel, },
|
|
|
|
|
{ category: 'Itinerary Arrangements', item: 'Travel Advisor’s Planning', value: evaluationScores.FRTAdvisor },
|
|
|
|
|
{ category: 'DMC Services', item: 'Guide', value: evaluationScores.FRTGuide, note: evaluationScores.FRTText, diff: { value: evaluationScoresDiff?.FRTGuide } },
|
|
|
|
|
{ category: 'DMC Services', item: 'Driver & Vehicle', value: evaluationScores.FRTGriver, diff: { value: evaluationScoresDiff?.FRTGriver } },
|
|
|
|
|
{ category: 'DMC Services', item: 'Food Arrangement', value: evaluationScores.FRTMeal, diff: { value: evaluationScoresDiff?.FRTMeal } },
|
|
|
|
|
{ category: 'DMC Services', item: 'Activity', value: evaluationScores.FRTProduct, diff: { value: evaluationScoresDiff?.FRTProduct } },
|
|
|
|
|
{ category: 'Itinerary Arrangements', item: 'Hotel', value: evaluationScores.FRTHotel, diff: { value: evaluationScoresDiff?.FRTHotel } },
|
|
|
|
|
{ category: 'Itinerary Arrangements', item: 'Travel Advisor’s Planning', value: evaluationScores.FRTAdvisor, diff: { value: evaluationScoresDiff?.FRTAdvisor } },
|
|
|
|
|
];
|
|
|
|
|
const columns_evaluation = [
|
|
|
|
|
{ title: 'Category', dataIndex: 'category', key: 'category',align: 'center', onCell: (_, index) => ({ rowSpan: index === 0 ? 4 : index === 4 ? 2 : 0 }) },
|
|
|
|
|
{ title: 'Item', dataIndex: 'item', key: 'item', align: 'center' },
|
|
|
|
|
{ title: 'Your Scores', dataIndex: 'value', key: 'value',align: 'center', },
|
|
|
|
|
{ title: 'Your Scores', dataIndex: 'value', key: 'value',align: 'left', render: (text, { diff }) => <>{text}<VSTag diffData={diff?.value} diffPercent={diff?.value ? comm.fixTo2Decimals((text-diff.value)/diff.value*100) : 0} /></> },
|
|
|
|
|
{ title: 'Note', dataIndex: 'note', key: 'note',align: 'center', onCell: (_, index) => ({ rowSpan: index === 0 ? 7 : 0 })},
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
@ -40,8 +59,8 @@ function Index() {
|
|
|
|
|
{ title: '3 scores', dataIndex: 'stand_3', key: 'stand_3', align: 'center', onCell: (_, index) => ({ colSpan: (index === 2 || index===4) ? 3 : 1 }) },
|
|
|
|
|
{ title: '4 scores', dataIndex: 'stand_4', key: 'stand_4',align: 'center',onCell: (_, index) => ({ colSpan: (index === 2 || index===4) ? 0 : 1 }) },
|
|
|
|
|
{ title: '5 scores', dataIndex: 'stand_5', key: 'stand_5',align: 'center',onCell: (_, index) => ({ colSpan: (index === 2 || index===4) ? 0 : 1 }) },
|
|
|
|
|
{ title: 'Your Scores', dataIndex: 'value', key: 'value',align: 'center', },
|
|
|
|
|
{ title: 'Final Scores', dataIndex: 'final_score', key: 'final_score',align: 'center', onCell: (_, index) => ({ rowSpan: index === 0 ? 5 : 0 })},
|
|
|
|
|
{ title: 'Your Scores', dataIndex: 'value', key: 'value',align: 'center', render: (text, { diff }) => <>{text}<VSTag diffData={diff?.value} diffPercent={diff?.value ? comm.fixTo2Decimals((text-diff.value)/diff.value*100) : 0} /></> },
|
|
|
|
|
{ title: 'Final Scores', dataIndex: 'final_score', key: 'final_score',align: 'center', onCell: (_, index) => ({ rowSpan: index === 0 ? 5 : 0 }), render: (text, { diff }) => <>{text}<VSTag diffData={diff?.final_score} diffPercent={diff?.final_score ? comm.fixTo2Decimals((text-diff.final_score)/diff.final_score*100) : 0} /></> },
|
|
|
|
|
{ title: 'Note', dataIndex: 'note', key: 'note',align: 'center', },
|
|
|
|
|
];
|
|
|
|
|
const DMCData_customer_satisfaction = [
|
|
|
|
|
@ -53,6 +72,10 @@ function Index() {
|
|
|
|
|
value: evaluationScores.TPReviewRating,
|
|
|
|
|
final_score: evaluationScores.AvgCusSatisfaction,
|
|
|
|
|
note: evaluationScores.AvgCusSatisfaction,
|
|
|
|
|
diff: {
|
|
|
|
|
value: evaluationScoresDiff?.TPReviewRating,
|
|
|
|
|
final_score: evaluationScoresDiff?.AvgCusSatisfaction,
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
item: 'Post tour complaints',
|
|
|
|
|
@ -62,6 +85,9 @@ function Index() {
|
|
|
|
|
value: evaluationScores.PostTourComplaints,
|
|
|
|
|
// final_score: evaluationScores.AvgCusSatisfaction,
|
|
|
|
|
note: evaluationScores.PostTourComplaintsText,
|
|
|
|
|
diff: {
|
|
|
|
|
value: evaluationScoresDiff?.PostTourComplaints,
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
item: 'Complaints resolved during the tour',
|
|
|
|
|
@ -70,9 +96,24 @@ function Index() {
|
|
|
|
|
// stand_5: '0',
|
|
|
|
|
value: evaluationScores.ComplaintsDuringTour,
|
|
|
|
|
note: evaluationScores.ComplaintsDuringTourText,
|
|
|
|
|
diff: {
|
|
|
|
|
value: evaluationScoresDiff?.ComplaintsDuringTour,
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{ item: 'Customer photos', stand_3: '\\', stand_4: '30%', stand_5: '50%',
|
|
|
|
|
value: evaluationScores.CustomerPhotoRate,
|
|
|
|
|
note: evaluationScores.CustomerPhotoRateText,
|
|
|
|
|
diff: {
|
|
|
|
|
value: evaluationScoresDiff?.CustomerPhotoRate,
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{ item: 'Evaluation scores', stand_3: '4.5',
|
|
|
|
|
value: evaluationScores.EvaluationFormScore,
|
|
|
|
|
note: evaluationScores.EvaluationFormScoreText,
|
|
|
|
|
diff: {
|
|
|
|
|
value: evaluationScoresDiff?.EvaluationFormScore,
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{ item: 'Customer photos', stand_3: '\\', stand_4: '30%', stand_5: '50%', value: evaluationScores.CustomerPhotoRate, note: evaluationScores.CustomerPhotoRateText },
|
|
|
|
|
{ item: 'Evaluation scores', stand_3: '4.5', value: evaluationScores.EvaluationFormScore, note: evaluationScores.EvaluationFormScoreText },
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const columns_DMC_sopport_local = [
|
|
|
|
|
@ -80,8 +121,8 @@ function Index() {
|
|
|
|
|
{ title: '3 scores', dataIndex: 'stand_3', key: 'stand_3', align: 'center', },
|
|
|
|
|
{ title: '4 scores', dataIndex: 'stand_4', key: 'stand_4',align: 'center', },
|
|
|
|
|
{ title: '5 scores', dataIndex: 'stand_5', key: 'stand_5',align: 'center', },
|
|
|
|
|
{ title: 'Your Scores', dataIndex: 'value', key: 'value',align: 'center', },
|
|
|
|
|
{ title: 'Final Scores', dataIndex: 'final_score', key: 'final_score',align: 'center', onCell: (_, index) => ({ rowSpan: index === 0 ? 6 : 0 })},
|
|
|
|
|
{ title: 'Your Scores', dataIndex: 'value', key: 'value',align: 'center', render: (text, { diff }) => <>{text}<VSTag diffData={diff?.value} diffPercent={diff?.value ? comm.fixTo2Decimals((text-diff.value)/diff.value*100) : 0} /></> },
|
|
|
|
|
{ title: 'Final Scores', dataIndex: 'final_score', key: 'final_score',align: 'center', onCell: (_, index) => ({ rowSpan: index === 0 ? 6 : 0 }), render: (text, { diff }) => <>{text}<VSTag diffData={diff?.final_score} diffPercent={diff?.final_score ? comm.fixTo2Decimals((text-diff.final_score)/diff.final_score*100) : 0} /></> },
|
|
|
|
|
{ title: 'Note', dataIndex: 'note', key: 'note',align: 'center', },
|
|
|
|
|
];
|
|
|
|
|
const DMCData_sopport_local = [
|
|
|
|
|
@ -93,6 +134,10 @@ function Index() {
|
|
|
|
|
value: evaluationScores.ResponseEfficiency,
|
|
|
|
|
final_score: evaluationScores.AvgLocalResources,
|
|
|
|
|
note: evaluationScores.ResponseEfficiencyText,
|
|
|
|
|
diff: {
|
|
|
|
|
value: evaluationScoresDiff?.ResponseEfficiency,
|
|
|
|
|
final_score: evaluationScoresDiff?.AvgLocalResources,
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
item: 'Provide suggestions and alternatives',
|
|
|
|
|
@ -102,6 +147,9 @@ function Index() {
|
|
|
|
|
value: evaluationScores.ProvideSuggestions,
|
|
|
|
|
// final_score: evaluationScores.AvgCusSatisfaction,
|
|
|
|
|
note: evaluationScores.ProvideSuggestionsText,
|
|
|
|
|
diff: {
|
|
|
|
|
value: evaluationScoresDiff?.ProvideSuggestions,
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
item: 'Provide local tourism information',
|
|
|
|
|
@ -110,27 +158,48 @@ function Index() {
|
|
|
|
|
stand_5: '√',
|
|
|
|
|
value: evaluationScores.ProvideLocalInfo,
|
|
|
|
|
note: evaluationScores.ProvideLocalInfoText,
|
|
|
|
|
diff: {
|
|
|
|
|
value: evaluationScoresDiff?.ProvideLocalInfo,
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{ item: 'Assist in developing exclusive products',
|
|
|
|
|
stand_3: '\\',
|
|
|
|
|
stand_4: '\\',
|
|
|
|
|
stand_5: '√', value: evaluationScores.ExclusiveProducts, note: evaluationScores.ExclusiveProductsText },
|
|
|
|
|
stand_5: '√',
|
|
|
|
|
value: evaluationScores.ExclusiveProducts,
|
|
|
|
|
note: evaluationScores.ExclusiveProductsText,
|
|
|
|
|
diff: {
|
|
|
|
|
value: evaluationScoresDiff?.ExclusiveProducts,
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{ item: 'Dedicated tour guide team for AH',
|
|
|
|
|
stand_3: '\\',
|
|
|
|
|
stand_4: '√',
|
|
|
|
|
stand_5: '√', value: evaluationScores.DedicatedTourGuide, note: evaluationScores.DedicatedTourGuideText },
|
|
|
|
|
stand_5: '√',
|
|
|
|
|
value: evaluationScores.DedicatedTourGuide,
|
|
|
|
|
note: evaluationScores.DedicatedTourGuideText,
|
|
|
|
|
diff: {
|
|
|
|
|
value: evaluationScoresDiff?.DedicatedTourGuide,
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{ item: 'Partner hotels with contracted rate',
|
|
|
|
|
stand_3: '\\',
|
|
|
|
|
stand_4: '√',
|
|
|
|
|
stand_5: '√', value: evaluationScores.PartnerHotels, note: evaluationScores.PartnerHotelsText },
|
|
|
|
|
stand_5: '√',
|
|
|
|
|
value: evaluationScores.PartnerHotels,
|
|
|
|
|
note: evaluationScores.PartnerHotelsText,
|
|
|
|
|
diff: {
|
|
|
|
|
value: evaluationScoresDiff?.PartnerHotels,
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
const columns_DMC_pricing = [
|
|
|
|
|
{ title: 'Pricing & Settlement (20%)', dataIndex: 'item', key: 'item',align: 'center', },
|
|
|
|
|
{ title: '3 scores', dataIndex: 'stand_3', key: 'stand_3', align: 'center', },
|
|
|
|
|
{ title: '4 scores', dataIndex: 'stand_4', key: 'stand_4',align: 'center', },
|
|
|
|
|
{ title: '5 scores', dataIndex: 'stand_5', key: 'stand_5',align: 'center', },
|
|
|
|
|
{ title: 'Your Scores', dataIndex: 'value', key: 'value',align: 'center', },
|
|
|
|
|
{ title: 'Final Scores', dataIndex: 'final_score', key: 'final_score',align: 'center', onCell: (_, index) => ({ rowSpan: index === 0 ? 3 : 0 })},
|
|
|
|
|
{ title: 'Your Scores', dataIndex: 'value', key: 'value',align: 'center', render: (text, { diff }) => <>{text}<VSTag diffData={diff?.value} diffPercent={diff?.value ? comm.fixTo2Decimals((text-diff.value)/diff.value*100) : 0} /></> },
|
|
|
|
|
{ title: 'Final Scores', dataIndex: 'final_score', key: 'final_score',align: 'center', onCell: (_, index) => ({ rowSpan: index === 0 ? 3 : 0 }), render: (text, { diff }) => <>{text}<VSTag diffData={diff?.final_score} diffPercent={diff?.final_score ? comm.fixTo2Decimals((text-diff.final_score)/diff.final_score*100) : 0} /></> },
|
|
|
|
|
{ title: 'Note', dataIndex: 'note', key: 'note',align: 'center', },
|
|
|
|
|
];
|
|
|
|
|
const DMCData_pricing = [
|
|
|
|
|
@ -142,6 +211,10 @@ function Index() {
|
|
|
|
|
value: evaluationScores.Quotation,
|
|
|
|
|
final_score: evaluationScores.AvgPricingAndSettlement,
|
|
|
|
|
note: evaluationScores.QuotationText,
|
|
|
|
|
diff: {
|
|
|
|
|
value: evaluationScoresDiff?.Quotation,
|
|
|
|
|
final_score: evaluationScoresDiff?.AvgPricingAndSettlement,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
item: 'Settlement',
|
|
|
|
|
@ -150,6 +223,7 @@ function Index() {
|
|
|
|
|
stand_5: 'Monthly settlement after the tours',
|
|
|
|
|
value: evaluationScores.Settlement,
|
|
|
|
|
note: evaluationScores.SettlementText,
|
|
|
|
|
diff: { value: evaluationScoresDiff?.Settlement },
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
item: 'Cancellation policy',
|
|
|
|
|
@ -158,6 +232,7 @@ function Index() {
|
|
|
|
|
stand_5: '1 day',
|
|
|
|
|
value: evaluationScores.CancellationPolicy,
|
|
|
|
|
note: evaluationScores.CancellationPolicyText,
|
|
|
|
|
diff: { value: evaluationScoresDiff?.CancellationPolicy },
|
|
|
|
|
},];
|
|
|
|
|
|
|
|
|
|
const columns_primary = [
|
|
|
|
|
@ -165,48 +240,66 @@ function Index() {
|
|
|
|
|
title: 'Groups',
|
|
|
|
|
dataIndex: 'Groups',
|
|
|
|
|
key: 'Groups',
|
|
|
|
|
render: (text, { diff }) => <>{text}<VSTag diffData={diff?.Groups} diffPercent={diff?.Groups ? comm.fixTo2Decimals((text-diff.Groups)/diff.Groups*100) : 0} /></>,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'Number of People',
|
|
|
|
|
dataIndex: 'PersonNum',
|
|
|
|
|
key: 'PersonNum',
|
|
|
|
|
render: (text, { diff }) => <>{text}<VSTag diffData={diff?.PersonNum} diffPercent={diff?.PersonNum ? comm.fixTo2Decimals((text-diff.PersonNum)/diff.PersonNum*100) : 0} /></>,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'Transaction Amount(USD)',
|
|
|
|
|
dataIndex: 'AmountUSD',
|
|
|
|
|
key: 'AmountUSD',
|
|
|
|
|
render: (value) => comm.formatPrice(value),
|
|
|
|
|
render: (value, { diff }) => <>{comm.formatPrice(value)}<VSTag diffData={diff?.AmountUSD} diffPercent={diff?.AmountUSD ? comm.fixTo2Decimals(value/diff.AmountUSD*100) : 0} /></>,
|
|
|
|
|
//
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'Evaluation Score',
|
|
|
|
|
dataIndex: 'EvaluationScore',
|
|
|
|
|
key: 'EvaluationScore',
|
|
|
|
|
render: (text, { diff }) => <>{text}<VSTag diffData={diff?.EvaluationScore} diffPercent={diff?.EvaluationScore ? comm.fixTo2Decimals((text-diff.EvaluationScore)/diff.EvaluationScore*100) : 0} /></>,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'TP Reviews',
|
|
|
|
|
dataIndex: 'TPReviews',
|
|
|
|
|
key: 'TPReviews',
|
|
|
|
|
render: (text, { diff }) => <>{text}<VSTag diffData={diff?.TPReviews} diffPercent={diff?.TPReviews ? comm.fixTo2Decimals((text-diff.TPReviews)/diff.TPReviews*100) : 0} /></>,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'TP Reviews Rate',
|
|
|
|
|
dataIndex: 'TPReviewRate',
|
|
|
|
|
key: 'TPReviewRate',
|
|
|
|
|
render: (value) => comm.formatPercent(value),
|
|
|
|
|
render: (text, { diff }) => <>{comm.formatPercent(text)}<VSTag diffData={diff?.TPReviewRate} diffPercent={diff?.TPReviewRate ? comm.fixTo2Decimals((text-diff.TPReviewRate)/diff.TPReviewRate*100) : 0} /></>,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'Complaints',
|
|
|
|
|
dataIndex: 'Complaints',
|
|
|
|
|
key: 'Complaints',
|
|
|
|
|
render: (text, { diff }) => <>{text}<VSTag diffData={diff?.Complaints} diffPercent={diff?.Complaints ? comm.fixTo2Decimals((text-diff.Complaints)/diff.Complaints*100) : 0} /></>,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'Complaint Rate',
|
|
|
|
|
dataIndex: 'ComplaintRate',
|
|
|
|
|
key: 'ComplaintRate',
|
|
|
|
|
render: (value) => comm.formatPercent(value),
|
|
|
|
|
render: (text, { diff }) => <>{comm.formatPercent(text)}<VSTag diffData={diff?.ComplaintRate} diffPercent={diff?.ComplaintRate ? comm.fixTo2Decimals((text-diff.ComplaintRate)/diff.ComplaintRate*100) : 0} /></>,
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const columns_month = [{ title: 'Date', dataIndex: 'VMonth', key: 'VMonth' }, ...columns_primary];
|
|
|
|
|
const columns_month = [
|
|
|
|
|
{
|
|
|
|
|
title: 'Date',
|
|
|
|
|
dataIndex: 'VMonth',
|
|
|
|
|
key: 'VMonth',
|
|
|
|
|
render: (text, { diff }) => (
|
|
|
|
|
<>
|
|
|
|
|
{text} {diff?.VMonth ? ` VS ${diff.VMonth}` : ''}
|
|
|
|
|
</>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
...columns_primary,
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const columns_guide = [
|
|
|
|
|
{
|
|
|
|
|
@ -218,33 +311,38 @@ function Index() {
|
|
|
|
|
title: 'Average Scores',
|
|
|
|
|
dataIndex: 'VAverage',
|
|
|
|
|
key: 'VAverage',
|
|
|
|
|
render: (text, { diff }) => <>{text}<VSTag diffData={diff?.VAverage} diffPercent={diff?.VAverage ? comm.fixTo2Decimals((text-diff.VAverage)/diff.VAverage*100) : 0} /></>,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'Group Numbers',
|
|
|
|
|
dataIndex: 'ReceptionGroups',
|
|
|
|
|
key: 'ReceptionGroups',
|
|
|
|
|
render: (text, { diff }) => <>{text}<VSTag diffData={diff?.ReceptionGroups} diffPercent={diff?.ReceptionGroups ? comm.fixTo2Decimals((text-diff.ReceptionGroups)/diff.ReceptionGroups*100) : 0} /></>,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'TP Reviews',
|
|
|
|
|
dataIndex: 'CommendNum',
|
|
|
|
|
key: 'CommendNum',
|
|
|
|
|
render: (text, { diff }) => <>{text}<VSTag diffData={diff?.CommendNum} diffPercent={diff?.CommendNum ? comm.fixTo2Decimals((text-diff.CommendNum)/diff.CommendNum*100) : 0} /></>,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'TP Review Rate',
|
|
|
|
|
dataIndex: 'CommendRate',
|
|
|
|
|
key: 'CommendRate',
|
|
|
|
|
render: (value) => comm.formatPercent(value),
|
|
|
|
|
// render: (value) => comm.formatPercent(value),
|
|
|
|
|
render: (text, { diff }) => <>{comm.formatPercent(text)}<VSTag diffData={diff?.CommendRate ? comm.formatPercent(diff?.CommendRate || 0) : void 0} diffPercent={diff?.CommendRate ? comm.fixTo2Decimals((text-diff.CommendRate)/diff.CommendRate*100) : 0} /></>,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'Complaints',
|
|
|
|
|
dataIndex: 'Complaints',
|
|
|
|
|
key: 'Complaints',
|
|
|
|
|
render: (text, { diff }) => <>{text}<VSTag diffData={diff?.Complaints} diffPercent={diff?.Complaints ? comm.fixTo2Decimals((text-diff.Complaints)/diff.Complaints*100) : 0} /></>,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'Complaint Rate',
|
|
|
|
|
dataIndex: 'ComplaintRate',
|
|
|
|
|
key: 'ComplaintRate',
|
|
|
|
|
render: (value) => comm.formatPercent(value),
|
|
|
|
|
render: (text, { diff }) => <>{comm.formatPercent(text)}<VSTag diffData={diff?.ComplaintRate ? comm.formatPercent(diff?.ComplaintRate || 0) : void 0} diffPercent={diff?.ComplaintRate ? comm.fixTo2Decimals((text-diff.ComplaintRate)/diff.ComplaintRate*100) : 0} /></>,
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
@ -274,6 +372,22 @@ function Index() {
|
|
|
|
|
overrides: { pdf: { compress: true }, canvas: { useCORS: true } },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const onGetData = async (formVal) => {
|
|
|
|
|
reset();
|
|
|
|
|
const fixDiff1 = dayjs(formVal.datesDiff1).startOf('month').format(DATE_FORMAT);
|
|
|
|
|
const res = await Promise.all([
|
|
|
|
|
getHWVendorScores(formVal.agency || travelAgencyId, formVal.startdate, formVal.enddate),
|
|
|
|
|
getHWProductScores(formVal.agency || travelAgencyId, formVal.startdate, formVal.enddate),
|
|
|
|
|
getHWCommendScores(formVal.agency || travelAgencyId, formVal.startdate, formVal.enddate),
|
|
|
|
|
...(comm.isEmpty(formVal.datesDiff1) ? [] : [
|
|
|
|
|
getHWVendorScores(formVal.agency || travelAgencyId, fixDiff1, formVal.datesDiff2, true),
|
|
|
|
|
getHWProductScores(formVal.agency || travelAgencyId, fixDiff1, formVal.datesDiff2, true),
|
|
|
|
|
getHWCommendScores(formVal.agency || travelAgencyId, fixDiff1, formVal.datesDiff2, true)
|
|
|
|
|
])
|
|
|
|
|
]);
|
|
|
|
|
setLoading(false);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Space direction='vertical' style={{ width: '100%' }}>
|
|
|
|
|
{/* <Typography.Title level={3}></Typography.Title> */}
|
|
|
|
|
@ -286,15 +400,14 @@ function Index() {
|
|
|
|
|
fieldsConfig={{
|
|
|
|
|
shows: ['dates'],
|
|
|
|
|
fieldProps: {
|
|
|
|
|
dates: { label: 'Select Date', col: 12 },
|
|
|
|
|
dates: { label: 'Select Date', col: 12, hide_vs: false },
|
|
|
|
|
},
|
|
|
|
|
fieldComProps: { dates: { picker: 'month', presets: false } },
|
|
|
|
|
}}
|
|
|
|
|
confirmText={t('vendor:report.GetReport')}
|
|
|
|
|
onSubmit={(err, formVal, filedsVal) => {
|
|
|
|
|
getHWVendorScores(formVal.agency || travelAgencyId, formVal.startdate, formVal.enddate);
|
|
|
|
|
getHWProductScores(formVal.agency || travelAgencyId, formVal.startdate, formVal.enddate);
|
|
|
|
|
getHWCommendScores(formVal.agency || travelAgencyId, formVal.startdate, formVal.enddate);
|
|
|
|
|
// return false;
|
|
|
|
|
onGetData(formVal);
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</Col>
|
|
|
|
|
@ -318,7 +431,7 @@ function Index() {
|
|
|
|
|
Monthly Data
|
|
|
|
|
</Typography.Title>
|
|
|
|
|
</Divider>
|
|
|
|
|
<Table loading={loading} dataSource={vendorScoresData.MonthlyData} columns={columns_month} pagination={false} bordered />
|
|
|
|
|
<Table loading={loading} dataSource={MonthlyData} columns={columns_month} pagination={false} bordered />
|
|
|
|
|
</Col>
|
|
|
|
|
|
|
|
|
|
<Col md={24} lg={24} xxl={16}>
|
|
|
|
|
@ -334,7 +447,7 @@ function Index() {
|
|
|
|
|
<Table key={'p'} dataSource={DMCData_pricing} columns={columns_DMC_pricing} pagination={false} bordered />
|
|
|
|
|
<Divider orientation='right'>
|
|
|
|
|
<Typography.Title level={3} type='danger'>
|
|
|
|
|
Final Scores: {evaluationScores.FinalScores}
|
|
|
|
|
Final Scores: {evaluationScores.FinalScores}{evaluationScoresDiff?.FinalScores ? <><VSTag diffData={evaluationScoresDiff.FinalScores} diffPercent={evaluationScoresDiff?.FinalScores ? comm.fixTo2Decimals((evaluationScores.FinalScores-evaluationScoresDiff.FinalScores)/evaluationScoresDiff.FinalScores*100) : 0} /></> : ''}
|
|
|
|
|
</Typography.Title>
|
|
|
|
|
</Divider>
|
|
|
|
|
<br />
|
|
|
|
|
@ -373,28 +486,28 @@ function Index() {
|
|
|
|
|
Tour Guides Performence
|
|
|
|
|
</Typography.Title>
|
|
|
|
|
</Divider>
|
|
|
|
|
<Table dataSource={productScoresData.GuideScores} columns={columns_guide} pagination={false} bordered />
|
|
|
|
|
<Table dataSource={Object.values(guideData)} columns={columns_guide} pagination={false} bordered />
|
|
|
|
|
|
|
|
|
|
<Divider orientation='center'>
|
|
|
|
|
<Typography.Title level={3} type='success'>
|
|
|
|
|
TP Reviews
|
|
|
|
|
</Typography.Title>
|
|
|
|
|
</Divider>
|
|
|
|
|
<Table dataSource={commendScoresData.CommendScores} columns={columns_commend} pagination={false} bordered />
|
|
|
|
|
<Table dataSource={[...commendScoresData?.CommendScores || [], ...commendScoresDataDiff?.CommendScores || []]} columns={columns_commend} pagination={false} bordered />
|
|
|
|
|
|
|
|
|
|
<Divider orientation='center'>
|
|
|
|
|
<Typography.Title level={3} type='success'>
|
|
|
|
|
Complaints
|
|
|
|
|
</Typography.Title>
|
|
|
|
|
</Divider>
|
|
|
|
|
<Table dataSource={commendScoresData.ComplaintScores} columns={columns_commend} pagination={false} bordered />
|
|
|
|
|
<Table dataSource={[...commendScoresData?.ComplaintScores || [], ...commendScoresDataDiff?.ComplaintScores || []]} columns={columns_commend} pagination={false} bordered />
|
|
|
|
|
|
|
|
|
|
<Divider orientation='center'>
|
|
|
|
|
<Typography.Title level={3} type='success'>
|
|
|
|
|
Suggestions from Customers
|
|
|
|
|
</Typography.Title>
|
|
|
|
|
</Divider>
|
|
|
|
|
<Table dataSource={commendScoresData.CriticizeScores} columns={columns_commend} pagination={false} bordered />
|
|
|
|
|
<Table dataSource={[...commendScoresData?.CriticizeScores || [], ...commendScoresDataDiff?.CriticizeScores || []]} columns={columns_commend} pagination={false} bordered />
|
|
|
|
|
</Col>
|
|
|
|
|
</Row>
|
|
|
|
|
</Space>
|
|
|
|
|
|