Update: 2026-06-22 00:31:28
This commit is contained in:
@@ -28,6 +28,10 @@ class MarketingController extends GetxController {
|
||||
fetchAnomalies();
|
||||
fetchCampaignsLog();
|
||||
fetchPriceComparison();
|
||||
fetchPriceGapHeatmap();
|
||||
fetchMarketShareAnalytics();
|
||||
fetchAiPricePrediction();
|
||||
fetchWinbackTargets();
|
||||
}
|
||||
|
||||
// --- Autopilot Status Toggle ---
|
||||
@@ -187,4 +191,158 @@ class MarketingController extends GetxController {
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
// --- What-If Simulator State ---
|
||||
double? simulatedPci;
|
||||
double? simulatedMarketShare;
|
||||
String? simulatorRecommendationStatus;
|
||||
String? simulatorRecommendationMessage;
|
||||
|
||||
Future<void> runWhatIfSimulation(String proposedSpeedPrice) async {
|
||||
isLoading = true;
|
||||
update();
|
||||
try {
|
||||
Map<String, dynamic> params = {
|
||||
'speed_price': proposedSpeedPrice
|
||||
};
|
||||
if (selectedCountry != 'All') {
|
||||
params['country_code'] = selectedCountry;
|
||||
} else {
|
||||
params['country_code'] = 'SY'; // Fallback
|
||||
}
|
||||
|
||||
var res = await CRUD().post(
|
||||
link: AppLink.whatIfSimulator,
|
||||
payload: params,
|
||||
);
|
||||
if (res is Map && res['status'] == 'success') {
|
||||
final data = res['message'];
|
||||
if (data is Map) {
|
||||
simulatedPci = (data['simulated_pci'] ?? 0.0).toDouble();
|
||||
simulatedMarketShare = (data['simulated_market_share_percent'] ?? 0.0).toDouble();
|
||||
simulatorRecommendationStatus = data['recommendation_status'];
|
||||
simulatorRecommendationMessage = data['recommendation_message'];
|
||||
}
|
||||
} else {
|
||||
Get.snackbar("Simulation Error", res['message'] ?? "Failed to run simulation");
|
||||
}
|
||||
} catch (e) {
|
||||
Get.snackbar("Error", "Network error during simulation");
|
||||
} finally {
|
||||
isLoading = false;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
// --- Heatmap State ---
|
||||
List heatmapData = [];
|
||||
double currentSiroPriceHeatmap = 0.0;
|
||||
|
||||
Future<void> fetchPriceGapHeatmap() async {
|
||||
try {
|
||||
Map<String, dynamic> params = {};
|
||||
if (selectedCountry != 'All') {
|
||||
params['country_code'] = selectedCountry;
|
||||
} else {
|
||||
params['country_code'] = 'SY'; // Fallback
|
||||
}
|
||||
|
||||
var res = await CRUD().post(
|
||||
link: AppLink.getPriceGapHeatmap,
|
||||
payload: params,
|
||||
);
|
||||
if (res is Map && res['status'] == 'success') {
|
||||
final data = res['message'];
|
||||
if (data is Map) {
|
||||
heatmapData = data['heatmap_data'] ?? [];
|
||||
currentSiroPriceHeatmap = (data['current_siro_price_per_km'] ?? 0.0).toDouble();
|
||||
update();
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// Silently fail
|
||||
}
|
||||
}
|
||||
|
||||
// --- Market Share Analytics ---
|
||||
List marketShareData = [];
|
||||
Future<void> fetchMarketShareAnalytics() async {
|
||||
try {
|
||||
Map<String, dynamic> params = {};
|
||||
if (selectedCountry != 'All') {
|
||||
params['country_code'] = selectedCountry;
|
||||
} else {
|
||||
params['country_code'] = 'SY';
|
||||
}
|
||||
|
||||
var res = await CRUD().post(
|
||||
link: AppLink.getMarketShareAnalytics,
|
||||
payload: params,
|
||||
);
|
||||
if (res is Map && res['status'] == 'success') {
|
||||
marketShareData = res['historical_data'] ?? [];
|
||||
update();
|
||||
}
|
||||
} catch (e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
// --- AI Price Prediction ---
|
||||
String? aiPredictionMessage;
|
||||
List predictedSurgeHours = [];
|
||||
Future<void> fetchAiPricePrediction() async {
|
||||
try {
|
||||
Map<String, dynamic> params = {};
|
||||
if (selectedCountry != 'All') {
|
||||
params['country_code'] = selectedCountry;
|
||||
} else {
|
||||
params['country_code'] = 'SY';
|
||||
}
|
||||
|
||||
var res = await CRUD().post(
|
||||
link: AppLink.aiPricePrediction,
|
||||
payload: params,
|
||||
);
|
||||
if (res is Map && res['status'] == 'success') {
|
||||
aiPredictionMessage = res['ai_analysis_message'];
|
||||
predictedSurgeHours = res['predicted_surge_hours'] ?? [];
|
||||
update();
|
||||
}
|
||||
} catch (e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
// --- Win-Back Targets ---
|
||||
List winbackTargets = [];
|
||||
int winbackTotalCount = 0;
|
||||
Future<void> fetchWinbackTargets() async {
|
||||
try {
|
||||
Map<String, dynamic> params = {};
|
||||
if (selectedCountry != 'All') {
|
||||
params['country_code'] = selectedCountry;
|
||||
} else {
|
||||
params['country_code'] = 'SY';
|
||||
}
|
||||
|
||||
var res = await CRUD().post(
|
||||
link: AppLink.winbackHotspotTargets,
|
||||
payload: params,
|
||||
);
|
||||
if (res is Map && res['status'] == 'success') {
|
||||
winbackTargets = res['targets'] ?? [];
|
||||
winbackTotalCount = res['total_targets'] ?? 0;
|
||||
update();
|
||||
}
|
||||
} catch (e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
// Initially fetch these too if needed, but fetch them specifically when country changes
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user