@@ -33,6 +33,13 @@ class Order extends Generator {
3333 */
3434 const SECOND_REFUND_MAX_DAYS = 30 ;
3535
36+ /**
37+ * Pre-generated dates for batch order creation (ensures chronological order by ID).
38+ *
39+ * @var array|null
40+ */
41+ protected static $ batch_dates = null ;
42+
3643 /**
3744 * Return a new order.
3845 *
@@ -236,17 +243,26 @@ public static function batch( $amount, array $args = array() ) {
236243 return $ amount ;
237244 }
238245
246+ // Pre-generate dates if date-start is provided
247+ // This ensures chronological order: lower order IDs = earlier dates
248+ if ( ! empty ( $ args ['date-start ' ] ) ) {
249+ self ::$ batch_dates = self ::generate_batch_dates ( $ amount , $ args );
250+ }
251+
239252 $ order_ids = array ();
240253
241254 for ( $ i = 1 ; $ i <= $ amount ; $ i ++ ) {
242255 $ order = self ::generate ( true , $ args );
243- if ( ! $ order ) {
256+ if ( ! $ order instanceof \WC_Order ) {
244257 error_log ( "Batch generation failed: Order {$ i } of {$ amount } could not be generated " );
245258 continue ;
246259 }
247260 $ order_ids [] = $ order ->get_id ();
248261 }
249262
263+ // Clear batch dates after generation
264+ self ::$ batch_dates = null ;
265+
250266 return $ order_ids ;
251267 }
252268
@@ -283,10 +299,18 @@ public static function get_customer() {
283299 * between `date-start` and the current date. You can pass an `end-date` and a random date between start
284300 * and end will be chosen.
285301 *
302+ * In batch mode with date-start set, dates are pre-generated and sorted chronologically,
303+ * ensuring lower order IDs have earlier or equal dates.
304+ *
286305 * @param array $assoc_args CLI arguments.
287306 * @return string Date string (Y-m-d)
288307 */
289308 protected static function get_date_created ( $ assoc_args ) {
309+ // In batch mode, pop next date from pre-generated sorted array
310+ if ( null !== self ::$ batch_dates && ! empty ( self ::$ batch_dates ) ) {
311+ return array_shift ( self ::$ batch_dates );
312+ }
313+
290314 $ current = date ( 'Y-m-d ' , time () );
291315 if ( ! empty ( $ assoc_args ['date-start ' ] ) && empty ( $ assoc_args ['date-end ' ] ) ) {
292316 $ start = $ assoc_args ['date-start ' ];
@@ -298,14 +322,19 @@ protected static function get_date_created( $assoc_args ) {
298322 return $ current ;
299323 }
300324
301- $ dates = array ();
302- $ date = strtotime ( $ start );
303- while ( $ date <= strtotime ( $ end ) ) {
304- $ dates [] = date ( 'Y-m-d ' , $ date );
305- $ date = strtotime ( '+1 day ' , $ date );
325+ // Use timestamp-based random selection for single order generation
326+ $ start_timestamp = strtotime ( $ start );
327+ $ end_timestamp = strtotime ( $ end );
328+ $ days_between = (int ) ( ( $ end_timestamp - $ start_timestamp ) / DAY_IN_SECONDS );
329+
330+ // If start and end are the same day, return that date (time will be randomized in generate())
331+ if ( 0 === $ days_between ) {
332+ return date ( 'Y-m-d ' , $ start_timestamp );
306333 }
307334
308- return $ dates [ array_rand ( $ dates ) ];
335+ // Generate random offset in days and add to start timestamp
336+ $ random_days = wp_rand ( 0 , $ days_between );
337+ return date ( 'Y-m-d ' , $ start_timestamp + ( $ random_days * DAY_IN_SECONDS ) );
309338 }
310339
311340 /**
@@ -790,4 +819,47 @@ protected static function calculate_refund_date( $order, $previous_refund = null
790819 $ random_days = wp_rand ( 0 , $ max_days );
791820 return date ( 'Y-m-d H:i:s ' , strtotime ( $ base_date ->date ( 'Y-m-d H:i:s ' ) ) + ( $ random_days * DAY_IN_SECONDS ) );
792821 }
822+
823+ /**
824+ * Generate an array of sorted dates for batch order creation.
825+ * Ensures chronological order when creating multiple orders.
826+ *
827+ * @param int $count Number of dates to generate.
828+ * @param array $args Arguments containing date-start and optional date-end.
829+ * @return array Sorted array of date strings (Y-m-d).
830+ */
831+ protected static function generate_batch_dates ( $ count , $ args ) {
832+ $ current = date ( 'Y-m-d ' , time () );
833+
834+ if ( ! empty ( $ args ['date-start ' ] ) && empty ( $ args ['date-end ' ] ) ) {
835+ $ start = $ args ['date-start ' ];
836+ $ end = $ current ;
837+ } elseif ( ! empty ( $ args ['date-start ' ] ) && ! empty ( $ args ['date-end ' ] ) ) {
838+ $ start = $ args ['date-start ' ];
839+ $ end = $ args ['date-end ' ];
840+ } else {
841+ // No date range specified, return array of current dates
842+ return array_fill ( 0 , $ count , $ current );
843+ }
844+
845+ $ start_timestamp = strtotime ( $ start );
846+ $ end_timestamp = strtotime ( $ end );
847+ $ days_between = (int ) ( ( $ end_timestamp - $ start_timestamp ) / DAY_IN_SECONDS );
848+
849+ // If start and end dates are the same, return array of that date
850+ if ( 0 === $ days_between ) {
851+ return array_fill ( 0 , $ count , date ( 'Y-m-d ' , $ start_timestamp ) );
852+ }
853+
854+ $ dates = array ();
855+ for ( $ i = 0 ; $ i < $ count ; $ i ++ ) {
856+ $ random_days = wp_rand ( 0 , $ days_between );
857+ $ dates [] = date ( 'Y-m-d ' , $ start_timestamp + ( $ random_days * DAY_IN_SECONDS ) );
858+ }
859+
860+ // Sort chronologically so lower order IDs get earlier dates
861+ sort ( $ dates );
862+
863+ return $ dates ;
864+ }
793865}
0 commit comments