Bug: add configs for Calculate job




diff --git a/config/config.example.toml b/config/config.example.toml
index e6bbef7fddf..0d5eb5f4fa3 100644
--- a/config/config.example.toml
+++ b/config/config.example.toml
@@ -1203,7 +1203,10 @@ max_retries_per_day = 20
 max_retry_count_for_thirty_day = 20
 
 [revenue_recovery.recovery_timestamp] # Timestamp configuration for Revenue Recovery
-initial_timestamp_in_hours = 1          # number of hours added to start time for Decider service of Revenue Recovery
+initial_timestamp_in_seconds = 3600          # number of seconds added to start time for Decider service of Revenue Recovery
+job_schedule_buffer_time_in_seconds = 3600    # buffer time in seconds to schedule the job for Revenue Recovery
+reopen_workflow_buffer_time_in_seconds = 3600  # time in seconds to be added in scheduling for calculate workflow
+max_random_schedule_delay_in_seconds = 300  # max random delay in seconds to schedule the payment for Revenue Recovery
 
 [clone_connector_allowlist]
 merchant_ids = "merchant_ids"           # Comma-separated list of allowed merchant IDs
diff --git a/config/deployments/env_specific.toml b/config/deployments/env_specific.toml
index 40868da8f3f..77fef227921 100644
--- a/config/deployments/env_specific.toml
+++ b/config/deployments/env_specific.toml
@@ -410,11 +410,14 @@ max_retries_per_day = 20
 max_retry_count_for_thirty_day = 20
 
 [revenue_recovery.recovery_timestamp] # Timestamp configuration for Revenue Recovery
-initial_timestamp_in_hours = 1        # number of hours added to start time for Decider service of Revenue Recovery
+initial_timestamp_in_seconds = 3600        # number of seconds added to start time for Decider service of Revenue Recovery
+job_schedule_buffer_time_in_seconds = 3600 # time in seconds to be added in schedule time as a buffer 
+reopen_workflow_buffer_time_in_seconds = 3600  # time in seconds to be added in scheduling for calculate workflow
+max_random_schedule_delay_in_seconds = 300 # max random delay in seconds to schedule the payment for Revenue Recovery
 
 [chat]
 enabled = false                                # Enable or disable chat features
 hyperswitch_ai_host = "http://0.0.0.0:8000"    # Hyperswitch ai workflow host
 
 [proxy_status_mapping]
-proxy_connector_http_status_code = false    # If enabled, the http status code of the connector will be proxied in the response
\ No newline at end of file
+proxy_connector_http_status_code = false    # If enabled, the http status code of the connector will be proxied in the response
diff --git a/config/development.toml b/config/development.toml
index 7db6e74568b..4f898e07570 100644
--- a/config/development.toml
+++ b/config/development.toml
@@ -1302,7 +1302,10 @@ retry_algorithm_type = "cascading"
 redis_ttl_in_seconds=3888000
 
 [revenue_recovery.recovery_timestamp]
-initial_timestamp_in_hours = 1
+initial_timestamp_in_seconds = 3600
+job_schedule_buffer_time_in_seconds = 3600
+reopen_workflow_buffer_time_in_seconds = 3600
+max_random_schedule_delay_in_seconds = 300
 
 [revenue_recovery.card_config.amex]
 max_retries_per_day = 20
diff --git a/config/docker_compose.toml b/config/docker_compose.toml
index fd5a6a9a0c8..a11475d6cb6 100644
--- a/config/docker_compose.toml
+++ b/config/docker_compose.toml
@@ -1219,6 +1219,11 @@ max_retry_count_for_thirty_day = 20
 max_retries_per_day = 20
 max_retry_count_for_thirty_day = 20
 
+[revenue_recovery.recovery_timestamp] # Timestamp configuration for Revenue Recovery
+initial_timestamp_in_seconds = 3600        # number of seconds added to start time for Decider service of Revenue Recovery
+job_schedule_buffer_time_in_seconds = 3600  # time in seconds to be added in schedule time as a buffer 
+reopen_workflow_buffer_time_in_seconds = 60  # time in seconds to be added in scheduling for calculate workflow
+
 [clone_connector_allowlist]
 merchant_ids = "merchant_123, merchant_234"     # Comma-separated list of allowed merchant IDs
 connector_names = "stripe, adyen"               # Comma-separated list of allowed connector names
diff --git a/crates/router/src/core/revenue_recovery.rs b/crates/router/src/core/revenue_recovery.rs
index 206c5026a63..d63cbd5f906 100644
--- a/crates/router/src/core/revenue_recovery.rs
+++ b/crates/router/src/core/revenue_recovery.rs
@@ -56,8 +56,9 @@ pub async fn upsert_calculate_pcr_task(
     // Create process tracker ID in the format: CALCULATE_WORKFLOW_{payment_intent_id}
     let process_tracker_id = format!("{runner}_{task}_{}", payment_id.get_string_repr());
 
-    // Set scheduled time to 1 hour from now
-    let schedule_time = common_utils::date_time::now() + time::Duration::hours(1);
+    // Scheduled time is now because this will be the first entry in
+    // process tracker and we dont want to wait
+    let schedule_time = common_utils::date_time::now();
 
     let payment_attempt_id = payment_attempt_id
         .ok_or(error_stack::report!(
@@ -580,7 +581,13 @@ pub async fn perform_calculate_workflow(
                     update_calculate_job_schedule_time(
                         db,
                         process,
-                        time::Duration::minutes(15),
+                        time::Duration::seconds(
+                            state
+                                .conf
+                                .revenue_recovery
+                                .recovery_timestamp
+                                .job_schedule_buffer_time_in_seconds,
+                        ),
                         scheduled_token.scheduled_at,
                         &connector_customer_id,
                     )
@@ -607,7 +614,13 @@ pub async fn perform_calculate_workflow(
                             update_calculate_job_schedule_time(
                                 db,
                                 process,
-                                time::Duration::minutes(15),
+                                time::Duration::seconds(
+                                    state
+                                        .conf
+                                        .revenue_recovery
+                                        .recovery_timestamp
+                                        .job_schedule_buffer_time_in_seconds,
+                                ),
                                 Some(common_utils::date_time::now()),
                                 &connector_customer_id,
                             )
diff --git a/crates/router/src/core/revenue_recovery/types.rs b/crates/router/src/core/revenue_recovery/types.rs
index 1777f4cb22d..d2667cc63b0 100644
--- a/crates/router/src/core/revenue_recovery/types.rs
+++ b/crates/router/src/core/revenue_recovery/types.rs
@@ -1180,7 +1180,14 @@ pub async fn reopen_calculate_workflow_on_payment_failure(
             // 3. Set business status to QUEUED
             // 4. Schedule for immediate execution
             let new_retry_count = process.retry_count + 1;
-            let new_schedule_time = common_utils::date_time::now() + time::Duration::hours(1);
+            let new_schedule_time = common_utils::date_time::now()
+                + time::Duration::seconds(
+                    state
+                        .conf
+                        .revenue_recovery
+                        .recovery_timestamp
+                        .reopen_workflow_buffer_time_in_seconds,
+                );
 
             let pt_update = storage::ProcessTrackerUpdate::Update {
                 name: Some(task.to_string()),
diff --git a/crates/router/src/types/storage/revenue_recovery.rs b/crates/router/src/types/storage/revenue_recovery.rs
index 3c3df991d4f..5a3f9f1bf7e 100644
--- a/crates/router/src/types/storage/revenue_recovery.rs
+++ b/crates/router/src/types/storage/revenue_recovery.rs
@@ -77,13 +77,19 @@ pub struct RevenueRecoverySettings {
 
 #[derive(Debug, serde::Deserialize, Clone)]
 pub struct RecoveryTimestamp {
-    pub initial_timestamp_in_hours: i64,
+    pub initial_timestamp_in_seconds: i64,
+    pub job_schedule_buffer_time_in_seconds: i64,
+    pub reopen_workflow_buffer_time_in_seconds: i64,
+    pub max_random_schedule_delay_in_seconds: i64,
 }
 
 impl Default for RecoveryTimestamp {
     fn default() -> Self {
         Self {
-            initial_timestamp_in_hours: 1,
+            initial_timestamp_in_seconds: 1,
+            job_schedule_buffer_time_in_seconds: 15,
+            reopen_workflow_buffer_time_in_seconds: 60,
+            max_random_schedule_delay_in_seconds: 300,
         }
     }
 }
diff --git a/crates/router/src/workflows/revenue_recovery.rs b/crates/router/src/workflows/revenue_recovery.rs
index 4d42be64f9a..b85ebd3ff11 100644
--- a/crates/router/src/workflows/revenue_recovery.rs
+++ b/crates/router/src/workflows/revenue_recovery.rs
@@ -324,9 +324,9 @@ pub(crate) async fn get_schedule_time_for_smart_retry(
     let start_time_primitive = payment_intent.created_at;
     let recovery_timestamp_config = &state.conf.revenue_recovery.recovery_timestamp;
 
-    let modified_start_time_primitive = start_time_primitive.saturating_add(time::Duration::hours(
-        recovery_timestamp_config.initial_timestamp_in_hours,
-    ));
+    let modified_start_time_primitive = start_time_primitive.saturating_add(
+        time::Duration::seconds(recovery_timestamp_config.initial_timestamp_in_seconds),
+    );
 
     let start_time_proto = date_time::convert_to_prost_timestamp(modified_start_time_primitive);
 
@@ -550,7 +550,8 @@ pub async fn get_token_with_schedule_time_based_on_retry_algorithm_type(
             .change_context(errors::ProcessTrackerError::EApiErrorResponse)?;
         }
     }
-    let delayed_schedule_time = scheduled_time.map(add_random_delay_to_schedule_time);
+    let delayed_schedule_time =
+        scheduled_time.map(|time| add_random_delay_to_schedule_time(state, time));
 
     Ok(delayed_schedule_time)
 }
@@ -776,10 +777,16 @@ pub async fn check_hard_decline(
 
 #[cfg(feature = "v2")]
 pub fn add_random_delay_to_schedule_time(
+    state: &SessionState,
     schedule_time: time::PrimitiveDateTime,
 ) -> time::PrimitiveDateTime {
     let mut rng = rand::thread_rng();
-    let random_secs = rng.gen_range(1..=3600);
+    let delay_limit = state
+        .conf
+        .revenue_recovery
+        .recovery_timestamp
+        .max_random_schedule_delay_in_seconds;
+    let random_secs = rng.gen_range(1..=delay_limit);
     logger::info!("Adding random delay of {random_secs} seconds to schedule time");
     schedule_time + time::Duration::seconds(random_secs)
 }

## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [ ] Bugfix
- [ ] New feature
- [ ] Enhancement
- [x] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description
<!-- Describe your changes in detail -->
Add configs for calculate job

### Additional Changes

- [ ] This PR modifies the API contract
- [ ] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

<!--
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
2. `crates/router/src/configs`
3. `loadtest/config`
-->


## Motivation and Context
<!--
Why is this change required? What problem does it solve?
If it fixes an open issue, please link to the issue here.

If you don't have an issue, we'd recommend starting with one first so the PR
can focus on the implementation (unless it is an obvious bug or documentation fix
that will have little conversation).
-->


## How did you test it?
<!--
Did you write an integration/unit/API test to verify the code changes?
Or did you test this change manually (provide relevant screenshots)?
-->


## Checklist
<!-- Put an `x` in the boxes that apply -->

- [x] I formatted the code `cargo +nightly fmt --all`
- [ ] I addressed lints thrown by `cargo clippy`
- [ ] I reviewed the submitted code
- [ ] I added unit tests for my changes where possible
