CustomOrdersTableController.php
3 months ago
DataSynchronizer.php
7 months ago
LegacyDataCleanup.php
1 year ago
LegacyDataHandler.php
5 months ago
OrdersTableDataStore.php
1 month ago
OrdersTableDataStoreMeta.php
1 year ago
OrdersTableFieldQuery.php
2 years ago
OrdersTableMetaQuery.php
1 year ago
OrdersTableQuery.php
1 month ago
OrdersTableRefundDataStore.php
1 month ago
OrdersTableSearchQuery.php
11 months ago
OrdersTableRefundDataStore.php
222 lines
| 1 | <?php |
| 2 | /** |
| 3 | * Order refund data store. Refunds are based on orders (essentially negative orders) but there is slight difference in how we save them. |
| 4 | * For example, order save hooks etc can't be fired when saving refund, so we need to do it a separate datastore. |
| 5 | */ |
| 6 | |
| 7 | namespace Automattic\WooCommerce\Internal\DataStores\Orders; |
| 8 | |
| 9 | use \WC_Cache_Helper; |
| 10 | use \WC_Meta_Data; |
| 11 | |
| 12 | /** |
| 13 | * Class OrdersTableRefundDataStore. |
| 14 | */ |
| 15 | class OrdersTableRefundDataStore extends OrdersTableDataStore { |
| 16 | |
| 17 | /** |
| 18 | * Data stored in meta keys, but not considered "meta" for refund. |
| 19 | * |
| 20 | * @var string[] |
| 21 | */ |
| 22 | protected $internal_meta_keys = array( |
| 23 | '_refund_amount', |
| 24 | '_refund_reason', |
| 25 | '_refunded_by', |
| 26 | '_refunded_payment', |
| 27 | ); |
| 28 | |
| 29 | /** |
| 30 | * We do not have and use all the getters and setters from OrderTableDataStore, so we only select the props we actually need. |
| 31 | * |
| 32 | * @var \string[][] |
| 33 | */ |
| 34 | protected $operational_data_column_mapping = array( |
| 35 | 'id' => array( 'type' => 'int' ), |
| 36 | 'order_id' => array( 'type' => 'int' ), |
| 37 | 'woocommerce_version' => array( |
| 38 | 'type' => 'string', |
| 39 | 'name' => 'version', |
| 40 | ), |
| 41 | 'prices_include_tax' => array( |
| 42 | 'type' => 'bool', |
| 43 | 'name' => 'prices_include_tax', |
| 44 | ), |
| 45 | 'coupon_usages_are_counted' => array( |
| 46 | 'type' => 'bool', |
| 47 | 'name' => 'recorded_coupon_usage_counts', |
| 48 | ), |
| 49 | 'shipping_tax_amount' => array( |
| 50 | 'type' => 'decimal', |
| 51 | 'name' => 'shipping_tax', |
| 52 | ), |
| 53 | 'shipping_total_amount' => array( |
| 54 | 'type' => 'decimal', |
| 55 | 'name' => 'shipping_total', |
| 56 | ), |
| 57 | 'discount_tax_amount' => array( |
| 58 | 'type' => 'decimal', |
| 59 | 'name' => 'discount_tax', |
| 60 | ), |
| 61 | 'discount_total_amount' => array( |
| 62 | 'type' => 'decimal', |
| 63 | 'name' => 'discount_total', |
| 64 | ), |
| 65 | ); |
| 66 | |
| 67 | /** |
| 68 | * Delete a refund order from database. |
| 69 | * |
| 70 | * @param \WC_Order $refund Refund object to delete. |
| 71 | * @param array $args Array of args to pass to the delete method. |
| 72 | * |
| 73 | * @return void |
| 74 | */ |
| 75 | public function delete( &$refund, $args = array() ) { |
| 76 | $refund_id = $refund->get_id(); |
| 77 | if ( ! $refund_id ) { |
| 78 | return; |
| 79 | } |
| 80 | |
| 81 | $refund_cache_key = WC_Cache_Helper::get_cache_prefix( 'orders' ) . 'refund_ids' . $refund->get_parent_id(); |
| 82 | wp_cache_delete( $refund_cache_key, 'orders' ); |
| 83 | |
| 84 | $this->delete_order_data_from_custom_order_tables( $refund_id ); |
| 85 | $refund->set_id( 0 ); |
| 86 | |
| 87 | $orders_table_is_authoritative = $refund->get_data_store()->get_current_class_name() === self::class; |
| 88 | |
| 89 | if ( $orders_table_is_authoritative ) { |
| 90 | $data_synchronizer = wc_get_container()->get( DataSynchronizer::class ); |
| 91 | if ( $data_synchronizer->data_sync_is_enabled() ) { |
| 92 | // Delete the associated post, which in turn deletes order items, etc. through {@see WC_Post_Data}. |
| 93 | // Once we stop creating posts for orders, we should do the cleanup here instead. |
| 94 | wp_delete_post( $refund_id ); |
| 95 | } else { |
| 96 | $this->handle_order_deletion_with_sync_disabled( $refund_id ); |
| 97 | } |
| 98 | } |
| 99 | } |
| 100 | |
| 101 | /** |
| 102 | * Helper method to set refund props. |
| 103 | * |
| 104 | * @param \WC_Order_Refund $refund Refund object. |
| 105 | * @param object $data DB data object. |
| 106 | * |
| 107 | * @since 8.0.0 |
| 108 | */ |
| 109 | protected function set_order_props_from_data( &$refund, $data ) { |
| 110 | parent::set_order_props_from_data( $refund, $data ); |
| 111 | foreach ( $data->meta_data as $meta ) { |
| 112 | switch ( $meta->meta_key ) { |
| 113 | case '_refund_amount': |
| 114 | $refund->set_amount( $meta->meta_value ); |
| 115 | break; |
| 116 | case '_refunded_by': |
| 117 | $refund->set_refunded_by( $meta->meta_value ); |
| 118 | break; |
| 119 | case '_refunded_payment': |
| 120 | $refund->set_refunded_payment( wc_string_to_bool( $meta->meta_value ) ); |
| 121 | break; |
| 122 | case '_refund_reason': |
| 123 | $refund->set_reason( $meta->meta_value ); |
| 124 | break; |
| 125 | } |
| 126 | } |
| 127 | } |
| 128 | |
| 129 | /** |
| 130 | * Method to create a refund in the database. |
| 131 | * |
| 132 | * @param \WC_Abstract_Order $refund Refund object. |
| 133 | */ |
| 134 | public function create( &$refund ) { |
| 135 | $refund->set_status( 'completed' ); // Refund are always marked completed. |
| 136 | $this->persist_save( $refund ); |
| 137 | } |
| 138 | |
| 139 | /** |
| 140 | * Update refund in database. |
| 141 | * |
| 142 | * @param \WC_Order $refund Refund object. |
| 143 | */ |
| 144 | public function update( &$refund ) { |
| 145 | $this->persist_updates( $refund ); |
| 146 | $refund->apply_changes(); |
| 147 | |
| 148 | // phpcs:disable WooCommerce.Commenting.CommentHooks.MissingSinceComment |
| 149 | /** |
| 150 | * This action is documented in woocommerce/includes/data-stores/class-wc-order-refund-data-store-cpt.php. |
| 151 | */ |
| 152 | do_action( 'woocommerce_update_order_refund', $refund->get_id(), $refund ); |
| 153 | // phpcs:enable |
| 154 | } |
| 155 | |
| 156 | /** |
| 157 | * Helper method that updates post meta based on an refund object. |
| 158 | * Mostly used for backwards compatibility purposes in this datastore. |
| 159 | * |
| 160 | * @param \WC_Order $refund Refund object. |
| 161 | */ |
| 162 | public function update_order_meta( &$refund ) { |
| 163 | parent::update_order_meta( $refund ); |
| 164 | |
| 165 | // Update additional props. |
| 166 | $updated_props = array(); |
| 167 | $meta_key_to_props = array( |
| 168 | '_refund_amount' => 'amount', |
| 169 | '_refunded_by' => 'refunded_by', |
| 170 | '_refunded_payment' => 'refunded_payment', |
| 171 | '_refund_reason' => 'reason', |
| 172 | ); |
| 173 | |
| 174 | $props_to_update = $this->get_props_to_update( $refund, $meta_key_to_props ); |
| 175 | foreach ( $props_to_update as $meta_key => $prop ) { |
| 176 | $meta_object = new WC_Meta_Data(); |
| 177 | $meta_object->key = $meta_key; |
| 178 | $meta_object->value = $refund->{"get_$prop"}( 'edit' ); |
| 179 | $existing_meta = $this->data_store_meta->get_metadata_by_key( $refund, $meta_key ); |
| 180 | if ( $existing_meta ) { |
| 181 | $existing_meta = $existing_meta[0]; |
| 182 | $meta_object->id = $existing_meta->id; |
| 183 | $this->update_meta( $refund, $meta_object ); |
| 184 | } else { |
| 185 | $this->add_meta( $refund, $meta_object ); |
| 186 | } |
| 187 | $updated_props[] = $prop; |
| 188 | } |
| 189 | |
| 190 | /** |
| 191 | * Fires after updating meta for a order refund. |
| 192 | * |
| 193 | * @since 2.7.0 |
| 194 | */ |
| 195 | do_action( 'woocommerce_order_refund_object_updated_props', $refund, $updated_props ); |
| 196 | } |
| 197 | |
| 198 | /** |
| 199 | * Get a title for the new post type. |
| 200 | * |
| 201 | * @return string |
| 202 | */ |
| 203 | protected function get_post_title() { |
| 204 | return sprintf( |
| 205 | /* translators: %s: Order date */ |
| 206 | __( 'Refund – %s', 'woocommerce' ), |
| 207 | ( new \DateTime( 'now' ) )->format( _x( 'M d, Y @ h:i A', 'Order date parsed by DateTime::format', 'woocommerce' ) ) // phpcs:ignore WordPress.WP.I18n.MissingTranslatorsComment, WordPress.WP.I18n.UnorderedPlaceholdersText |
| 208 | ); |
| 209 | } |
| 210 | |
| 211 | |
| 212 | /** |
| 213 | * Returns data store object to use backfilling. |
| 214 | * |
| 215 | * @return \WC_Order_Refund_Data_Store_CPT |
| 216 | */ |
| 217 | protected function get_post_data_store_for_backfill() { |
| 218 | return new \WC_Order_Refund_Data_Store_CPT(); |
| 219 | } |
| 220 | |
| 221 | } |
| 222 |