value. * * @var array * * @TODO move to extra. * this is a placeholder for meta-data objects not k->v pair. */ protected array $extra_data = [ //'amount' => '', 'reason' => '', 'refunded_by' => 0, 'refunded_payment' => false, ]; protected bool $allow_trash = false; public function __construct( $read = 0 ) { $this->internal_meta_keys[] = '_reason'; $this->internal_meta_keys[] = '_refunded_by'; $this->internal_meta_keys[] = '_refunded_payment'; $this->meta_key_to_props['_reason'] = 'reason'; $this->meta_key_to_props['_refunded_by'] = 'refunded_by'; $this->meta_key_to_props['_refunded_payment'] = 'refunded_payment'; unset( $this->data['payment_method'], $this->data['payment_method_title'] ); parent::__construct( $read ); } protected function read_db_data( $value, string $field = 'id' ): array { return array_merge( parent::read_db_data( $value, $field ), [ 'reason' => $this->get_metadata( '_reason' ), 'refunded_by' => $this->get_metadata( '_refunded_by' ), 'refunded_payment' => $this->get_metadata( '_refunded_payment' ), ] ); } /** * Get status - always completed for refunds. * * @param string $context What the value is for. Valid values are view and edit. * * @return string */ public function get_status( string $context = 'view' ): ?string { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass return OrderStatus::COMPLETED; } /** * Get refunded amount. * * @param string $context What the value is for. Valid values are view and edit. * * @return float|string */ public function get_amount( string $context = 'view' ) { return $this->get_total_amount( $context ); } public function get_total_amount( string $context = 'view' ) { return $this->get_total( $context ); } public function get_tax_amount( string $context = 'view' ) { return $this->get_total_tax( $context ); } /** * Get refund reason. * * @param string $context What the value is for. Valid values are view and edit. * * @return string */ public function get_reason( string $context = 'view' ): string { return (string) $this->get_prop( 'reason', $context ); } /** * Get ID of user who did the refund. * * @param string $context What the value is for. Valid values are view and edit. * * @return int */ public function get_refunded_by( string $context = 'view' ): int { return (int) $this->get_prop( 'refunded_by', $context ); } protected ?Customer $user = null; public function get_refunded_by_user() { if ( ! $this->user || ( is_a( $this->user, '\StoreEngine\Classes\Customer' ) && $this->user->get_id() !== $this->get_refunded_by() ) ) { $this->user = Helper::get_customer( $this->get_refunded_by() ); } return $this->user; } /** * Return if the payment was refunded via API. * * @param string $context What the value is for. Valid values are view and edit. * * @return bool */ public function get_refunded_payment( string $context = 'view' ): bool { return Formatting::string_to_bool( $this->get_prop( 'refunded_payment', $context ) ); } /** * Get formatted refunded amount. * * @return string */ public function get_formatted_refund_amount(): string { return apply_filters( 'storeengine/formatted_refund_amount', Formatting::price( $this->get_amount(), [ 'currency' => $this->get_currency() ] ), $this ); } /** * Set refunded amount. * * @param string|float|int $value Value to set. */ public function set_amount( $value ) { $this->set_total_amount( $value ); } public function set_total_amount( $amount ) { $this->set_total( $amount ); } /** * Set refund reason. * * @param string $value Value to set. */ public function set_reason( string $value ) { $this->set_prop( 'reason', $value ); } /** * Set refunded by. * * @param int|string $value Value to set. */ public function set_refunded_by( $value ) { $this->set_prop( 'refunded_by', absint( $value ) ); } /** * Set if the payment was refunded via API. * * @param bool|string $value Value to set. (yes|no|1|0|true|false) */ public function set_refunded_payment( $value ) { $this->set_prop( 'refunded_payment', Formatting::string_to_bool( $value ) ); } protected function query(): ?string { global $wpdb; return " SELECT o.id as o_id, o.parent_order_id as parent_order_id, o.*, p.id as operational_id, p.* FROM {$wpdb->prefix}storeengine_orders o LEFT JOIN {$wpdb->prefix}storeengine_order_operational_data p ON p.order_id = o.id LEFT JOIN {$wpdb->prefix}storeengine_orders_meta m ON m.order_id = o.id "; } protected function prepare_for_db( string $context = 'create' ): array { $data = []; $format = []; $props = [ 'status', 'currency', 'type', 'tax_amount', 'total_amount', 'customer_id', 'date_created_gmt', 'date_updated_gmt', 'parent_order_id', ]; if ( 'create' === $context ) { $this->set_date_prop( 'date_created_gmt', current_time( 'mysql', 1 ) ); } // Always set. $this->set_date_prop( 'date_updated_gmt', current_time( 'mysql', 1 ) ); foreach ( $props as $prop ) { $value = $this->{"get_$prop"}( 'edit' ); if ( $value && is_a( $value, StoreengineDatetime::class ) ) { $value = $this->prepare_date_for_db( $value ); } $format[] = $this->predict_format( $prop, $value ); $data[ $prop ] = $value; } return [ 'data' => apply_filters( 'storeengine/' . $this->object_type . '/db/' . $context, $data, $this ), 'format' => $format, ]; } protected function prepare_operational_data_for_db( string $context = 'create' ): array { $data = []; $format = []; $props = [ 'storeengine_version' => 'version', 'prices_include_tax' => 'prices_include_tax', 'coupon_usages_are_counted' => 'coupon_usages_are_counted', 'download_permission_granted' => 'download_permission_granted', 'cart_hash' => 'cart_hash', 'new_order_email_sent' => 'new_order_email_sent', 'order_key' => 'order_key', 'date_paid_gmt' => 'date_paid_gmt', 'date_completed_gmt' => 'date_completed_gmt', 'shipping_tax_amount' => 'shipping_tax_amount', 'shipping_total_amount' => 'shipping_total_amount', 'discount_tax_amount' => 'discount_tax_amount', 'discount_total_amount' => 'discount_total_amount', 'recorded_sales' => 'recorded_sales', ]; if ( 'create' === $context ) { $props['order_id'] = 'id'; } foreach ( $props as $key => $prop ) { $value = $this->{"get_$prop"}( 'edit' ); if ( $value && is_a( $value, StoreengineDatetime::class ) ) { $value = $this->prepare_date_for_db( $value ); } $format[] = $this->predict_format( $key, $value ); $data[ $key ] = $value; } return [ 'data' => apply_filters( 'storeengine/' . $this->object_type . '_operational_data/db/' . $context, $data, $this ), 'format' => $format, ]; } }