get_id() ) ) { return; } foreach ( $order->get_items() as $item_id => $item ) { $start = $item->get_meta( '_abfw_start' ); $end = $item->get_meta( '_abfw_end' ); if ( ! $start || ! $end ) { continue; } Repository::create( array( 'product_id' => (int) $item->get_product_id(), 'variation_id' => (int) $item->get_variation_id(), 'order_id' => (int) $order->get_id(), 'order_item_id' => (int) $item_id, 'customer_id' => (int) $order->get_customer_id(), 'start_date' => $start, 'end_date' => $end, 'units' => (int) $item->get_meta( '_abfw_units' ), 'quantity' => (int) $item->get_quantity(), 'status' => 'pending', ) ); } $this->catch_up( $order->get_id() ); } /** * Write back every booking the list is missing. * * @since 1.0.0 * @return int How many bookings were written. */ public function rebuild() { $written = 0; $page = 1; do { $orders = wc_get_orders( array( 'limit' => 50, 'page' => $page, 'orderby' => 'ID', 'order' => 'ASC', 'status' => array_keys( wc_get_order_statuses() ), ) ); foreach ( $orders as $order ) { $before = count( Repository::for_order( $order->get_id() ) ); $this->record( $order ); $written += count( Repository::for_order( $order->get_id() ) ) - $before; } ++$page; } while ( count( $orders ) === 50 ); return $written; } /** * Follow the order: a paid order holds its dates, a cancelled one frees them. * * @since 1.0.0 * @param int $order_id Order that changed. * @param string $from Previous status. * @param string $to New status. */ public function follow_order_status( $order_id, $from, $to ) { $lost = array( 'cancelled', 'refunded', 'failed' ); if ( in_array( $to, $lost, true ) ) { Repository::set_order_status( $order_id, 'cancelled' ); return; } // Only an order coming back to life starts over, so a step moved by hand stays. if ( in_array( $from, $lost, true ) ) { Repository::set_order_status( $order_id, 'pending' ); } $this->catch_up( $order_id ); } /** * Follow the dates of an order line corrected by hand. * * @since 1.0.1 * @param int $order_id Order holding the line. * @param int $order_item_id Line corrected. * @param array $dates New dates. */ public function follow_item( $order_id, $order_item_id, array $dates ) { Repository::move_item( $order_item_id, $dates ); $this->catch_up( $order_id ); } /** * Bring the bookings of an order to the step their dates deserve. * * @since 1.0.0 * @param int $order_id Order holding the bookings. */ private function catch_up( $order_id ) { foreach ( Repository::for_order( $order_id ) as $booking ) { if ( 'cancelled' === $booking->status ) { continue; } $next = Statuses::next_for( $booking ); if ( $next !== $booking->status ) { Repository::update_status( (int) $booking->id, $next ); } } } }