application_id)) { return; } // Out of scope if the application predates the release. No created_at // on the element, so this costs one memoised PK lookup — unlike // ConsumerApplicationObserver, which has the value in memory. if (!DatapointHelper::isEligible($element->application_id)) { return; } $redis = new RawRedisConnector(); $key = DatapointHelper::datapointKey($element->application_id); // Field names are the consumer_application_element column names — see // DatapointHelper::$approvalRequired. $fieldsData = [ 'product_name' => !empty($element->product_name) ? 1 : 0, 'installation_address_city' => !empty($element->installation_address_city) ? 1 : 0, 'installation_address_state' => !empty($element->installation_address_state) ? 1 : 0, 'installation_address_line_1' => !empty($element->installation_address_line_1) ? 1 : 0, 'installation_address_pincode' => !empty($element->installation_address_pincode) ? 1 : 0, 'solar_power_type' => !empty($element->solar_power_type) ? 1 : 0, 'type_of_customer' => !empty($element->type_of_customer) ? 1 : 0, 'inverter_monthly_power_bill' => !empty($element->inverter_monthly_power_bill) ? 1 : 0, 'inverter_KW_installation' => !empty($element->inverter_KW_installation) ? 1 : 0, 'inverter_gross_project_amount' => !empty($element->inverter_gross_project_amount) ? 1 : 0, 'inverter_power_savings' => !empty($element->inverter_power_savings) ? 1 : 0, ]; // write() records the flags, refreshes the TTL, and fires the // readiness notification when the hash was cold or a flag flipped. DatapointHelper::write($redis, $element->application_id, $fieldsData); // Applicant type 1 only — this observer owns no co-applicant fields, // and the co-applicant tier dispatches only from the consent paths. DatapointHelper::maybeDispatch($element->application_id, $redis, $key, $fieldsData, 1); } catch (\Exception $e) { \Log::error("ConsumerApplicationElementObserver Error: " . $e->getMessage()); } } }