# woocommerce-pos/1.10.16/includes/Abstracts/Store.php

WCPOS – Point of Sale (POS) plugin for WooCommerce, version 1.10.16. 682 lines.

- Page: https://pluginprobe.com/plugins/woocommerce-pos/1.10.16/code/includes/Abstracts/Store.php
- Raw: https://pluginprobe.com/plugins/woocommerce-pos/1.10.16/raw/includes/Abstracts/Store.php
- Modified: 2026-09-01T14:48:10+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/woocommerce-pos/1.10.16/code/includes/Abstracts/Store.php#L10-L20`.

```php
<?php
/**
 * Abstract Store class.
 *
 * @package WooCommerce\POS\Abstracts
 */

namespace WCPOS\WooCommercePOS\Abstracts;

use WCPOS\WooCommercePOS\Interfaces\StoreInterface;
use WCPOS\WooCommercePOS\Services\Receipt_I18n_Labels;
use WCPOS\WooCommercePOS\Services\Settings;
use WCPOS\WooCommercePOS\Services\Store_Defaults;
use WC_Countries;
use function wc_format_country_state_string;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Abstract Store class.
 *
 * Handles the store data, and provides CRUD methods.
 * Implements StoreInterface to ensure API consistency with Pro version.
 */
class Store extends \WC_Data implements StoreInterface {
	/**
	 * This is the name of this object type.
	 *
	 * @var string
	 */
	protected $object_type = 'store';

	/**
	 * Stores product data.
	 *
	 * @var array
	 */
	protected $data = array(
		'name'                        => '',
		'locale'                      => '',
		'timezone'                    => '',
		'store_address'               => '',
		'store_address_2'             => '',
		'store_city'                  => '',
		'store_postcode'              => '',
		'store_state'                 => '',
		'store_country'               => '',
		'default_customer_address'    => '',
		'calc_taxes'                  => '',
		'enable_coupons'              => '',
		'calc_discounts_sequentially' => '',
		'currency'                    => '',
		'currency_pos'                => '',
		'price_thousand_sep'          => '',
		'price_decimal_sep'           => '',
		'price_num_decimals'          => '',
		'prevent_overselling'         => false,
		'prices_include_tax'          => '',
		'tax_based_on'                => '',
		'tax_address'                 => array(
			'country'  => '',
			'state'    => '',
			'postcode' => '',
			'city'     => '',
		),
		'shipping_tax_class'          => '',
		'tax_round_at_subtotal'       => '',
		'tax_display_shop'            => '',
		'tax_display_cart'            => '',
		'price_display_suffix'        => '',
		'tax_total_display'           => '',
		'default_customer'            => 0,
		'default_customer_is_cashier' => false,
		// The merchant's consent to anonymous usage data + error reports. The POS
		// client reads it from here so its own error reporting follows the same
		// switch as the plugin's analytics (POS > Settings > General).
		'tracking_consent'            => 'undecided',
		// Pro properties (with WooCommerce defaults in free version).
		'url'                         => '',
		'phone'                       => '',
		'email'                       => '',
		'opening_hours'               => array(),
		'opening_hours_notes'         => '',
		'personal_notes'              => '',
		'policies_and_conditions'     => '',
		'footer_imprint'              => '',
		'tax_ids'                     => array(),
	);

	/**
	 * Construct the default POS store.
	 */
	public function __construct() {
		parent::__construct();
		$this->set_wordpress_settings();
		$this->set_woocommerce_general_settings();
		$this->set_woocommerce_tax_settings();
		$this->set_woocommerce_pos_settings();
		$this->set_pro_property_defaults();
	}

	/**
	 * Set WordPress settings.
	 */
	public function set_wordpress_settings() {
		$this->set_prop( 'locale', \get_locale() );
		$this->set_prop( 'timezone', \wp_timezone_string() );
	}

	/**
	 * Set WooCommerce general settings.
	 */
	public function set_woocommerce_general_settings() {
		$default_country = \WC_Admin_Settings::get_option( 'woocommerce_default_country' );
		$country_state_array = wc_format_country_state_string( $default_country );

		$this->set_prop( 'store_address', \WC_Admin_Settings::get_option( 'woocommerce_store_address' ) );
		$this->set_prop( 'store_address_2', \WC_Admin_Settings::get_option( 'woocommerce_store_address_2' ) );
		$this->set_prop( 'store_city', \WC_Admin_Settings::get_option( 'woocommerce_store_city' ) );
		$this->set_prop( 'store_state', $country_state_array['state'] );
		$this->set_prop( 'store_country', $country_state_array['country'] );
		// $this->set_prop( 'default_country', $default_country );
		$this->set_prop( 'store_postcode', \WC_Admin_Settings::get_option( 'woocommerce_store_postcode' ) );
		$this->set_prop( 'default_customer_address', \WC_Admin_Settings::get_option( 'woocommerce_default_customer_address' ) );
		$this->set_prop( 'calc_taxes', \WC_Admin_Settings::get_option( 'woocommerce_calc_taxes' ) );
		$this->set_prop( 'enable_coupons', \WC_Admin_Settings::get_option( 'woocommerce_enable_coupons' ) );
		$this->set_prop( 'calc_discounts_sequentially', \WC_Admin_Settings::get_option( 'woocommerce_calc_discounts_sequentially' ) );
		$this->set_prop( 'currency', \WC_Admin_Settings::get_option( 'woocommerce_currency' ) );
		$this->set_prop( 'currency_pos', \WC_Admin_Settings::get_option( 'woocommerce_currency_pos' ) );
		$this->set_prop( 'price_thousand_sep', \WC_Admin_Settings::get_option( 'woocommerce_price_thousand_sep' ) );
		$this->set_prop( 'price_decimal_sep', \WC_Admin_Settings::get_option( 'woocommerce_price_decimal_sep' ) );
		$this->set_prop( 'price_num_decimals', (int) \WC_Admin_Settings::get_option( 'woocommerce_price_num_decimals', 2 ) );
	}

	/**
	 * Set WooCommerce tax settings.
	 */
	public function set_woocommerce_tax_settings() {
		$this->set_prop( 'prices_include_tax', \WC_Admin_Settings::get_option( 'woocommerce_prices_include_tax' ) );
		$this->set_prop( 'tax_based_on', 'base' ); // default should be base, perhaps have a setting for this?
		$this->set_prop( 'shipping_tax_class', \WC_Admin_Settings::get_option( 'woocommerce_shipping_tax_class' ) );
		$this->set_prop( 'tax_round_at_subtotal', \WC_Admin_Settings::get_option( 'woocommerce_tax_round_at_subtotal' ) );
		$this->set_prop( 'tax_display_shop', \WC_Admin_Settings::get_option( 'woocommerce_tax_display_shop' ) );
		$this->set_prop( 'tax_display_cart', \WC_Admin_Settings::get_option( 'woocommerce_tax_display_cart' ) );
		$this->set_prop( 'price_display_suffix', \WC_Admin_Settings::get_option( 'woocommerce_price_display_suffix' ) );
		$this->set_prop( 'tax_total_display', \WC_Admin_Settings::get_option( 'woocommerce_tax_total_display' ) );

		// tax address is same as WooCommerce address by default.
		$country_state_array = wc_format_country_state_string( \WC_Admin_Settings::get_option( 'woocommerce_default_country' ) );

		$this->set_prop(
			'tax_address',
			array(
				'country' => $country_state_array['country'],
				'state' => $country_state_array['state'],
				'postcode' => \WC_Admin_Settings::get_option( 'woocommerce_store_postcode' ),
				'city' => \WC_Admin_Settings::get_option( 'woocommerce_store_city' ),
			)
		);
	}

	/**
	 * Set WooCommerce POS settings.
	 */
	public function set_woocommerce_pos_settings() {
		$this->set_prop( 'default_customer', Settings::instance()->default_customer_id() );
		$this->set_prop( 'default_customer_is_cashier', Settings::instance()->default_customer_is_cashier() );
		$this->set_prop( 'prevent_overselling', Settings::instance()->prevent_overselling_enabled() );
		// The POS client gates its OWN error reporting on this value, so it is a
		// send gate one hop away: read the persisted answer, not the filtered view.
		$this->set_prop( 'tracking_consent', Settings::instance()->raw_tracking_consent() );
	}

	/**
	 * Get the store data as an array.
	 *
	 * Extends the raw prop data with `receipt_i18n`, the receipt label
	 * dictionary resolved for this store's locale. The client persists it on
	 * the store record so offline/fallback receipt renders use the same
	 * translated labels as server-built receipt payloads (issue mono#1252).
	 * Computed here (not stored as a prop) so Pro's per-outlet locale
	 * override is applied before resolution.
	 *
	 * @return array
	 */
	public function get_data() {
		$data                 = parent::get_data();
		$data['receipt_i18n'] = Receipt_I18n_Labels::get_labels( (string) $this->get_locale() );

		return $data;
	}

	/**
	 * Get Store name.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_name( $context = 'view' ) {
		return $this->get_prop( 'name', $context );
	}

	/**
	 * Get Store locale.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_locale( $context = 'view' ) {
		return $this->get_prop( 'locale', $context );
	}


	/**
	 * Get Store timezone.
	 *
	 * Empty string means inherit the WordPress site timezone.
	 *
	 * @param string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_timezone( $context = 'view' ) {
		$value = $this->get_prop( 'timezone', $context );
		return is_string( $value ) ? $value : '';
	}

	/**
	 * Get Store address.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_store_address( $context = 'view' ) {
		return $this->get_prop( 'store_address', $context );
	}

	/**
	 * Get Store address 2.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_store_address_2( $context = 'view' ) {
		return $this->get_prop( 'store_address_2', $context );
	}

	/**
	 * Get Store city.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_store_city( $context = 'view' ) {
		return $this->get_prop( 'store_city', $context );
	}

	/**
	 * Get Store postcode.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_store_postcode( $context = 'view' ) {
		return $this->get_prop( 'store_postcode', $context );
	}

	/**
	 * Get Store country, eg: US:AL.
	 * This is of the form COUNTRYCODE:STATECODE to be consistent with the WooCommerce settings.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	// phpcs:disable Squiz.Commenting.InlineComment.InvalidEndChar -- Commented-out code.
	// public function get_default_country( $context = 'view' ) {
	// return $this->get_prop( 'default_country', $context );
	// }
	// phpcs:enable Squiz.Commenting.InlineComment.InvalidEndChar

	/**
	 * Get Store state code.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_store_state( $context = 'view' ) {
		return $this->get_prop( 'store_state', $context );
	}

	/**
	 * Get Store country code.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_store_country( $context = 'view' ) {
		return $this->get_prop( 'store_country', $context );
	}

	/**
	 * Get Store customer address.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_default_customer_address( $context = 'view' ) {
		return $this->get_prop( 'default_customer_address', $context );
	}

	/**
	 * Get Store calculate taxes.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_calc_taxes( $context = 'view' ) {
		return $this->get_prop( 'calc_taxes', $context );
	}

	/**
	 * Get Store enable coupons.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_enable_coupons( $context = 'view' ) {
		return $this->get_prop( 'enable_coupons', $context );
	}

	/**
	 * Get Store calculate discounts sequentially.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_calc_discounts_sequentially( $context = 'view' ) {
		return $this->get_prop( 'calc_discounts_sequentially', $context );
	}

	/**
	 * Get Store currency.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_currency( $context = 'view' ) {
		return $this->get_prop( 'currency', $context );
	}

	/**
	 * Get Store currency position.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_currency_position( $context = 'view' ) {
		return $this->get_prop( 'currency_pos', $context );
	}

	/**
	 * Get Store price thousand separator.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_price_thousand_separator( $context = 'view' ) {
		return $this->get_prop( 'price_thousand_sep', $context );
	}

	/**
	 * Get Store price decimal separator.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_price_decimal_separator( $context = 'view' ) {
		return $this->get_prop( 'price_decimal_sep', $context );
	}

	/**
	 * Get Store price number of decimals.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return int
	 */
	public function get_price_number_of_decimals( $context = 'view' ) {
		return $this->get_prop( 'price_num_decimals', $context );
	}

	/**
	 * Get Store prices include tax.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_prices_include_tax( $context = 'view' ) {
		return $this->get_prop( 'prices_include_tax', $context );
	}

	/**
	 * Get Store tax based on.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_tax_based_on( $context = 'view' ) {
		return $this->get_prop( 'tax_based_on', $context );
	}

	/**
	 * Get Store tax address.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return array
	 */
	public function get_tax_address( $context = 'view' ) {
		return $this->get_prop( 'tax_address', $context );
	}

	/**
	 * Get Store shipping tax class.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_shipping_tax_class( $context = 'view' ) {
		return $this->get_prop( 'shipping_tax_class', $context );
	}

	/**
	 * Get Store tax round at subtotal.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_tax_round_at_subtotal( $context = 'view' ) {
		return $this->get_prop( 'tax_round_at_subtotal', $context );
	}

	/**
	 * Get Store tax display shop.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_tax_display_shop( $context = 'view' ) {
		return $this->get_prop( 'tax_display_shop', $context );
	}

	/**
	 * Get Store tax display cart.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_tax_display_cart( $context = 'view' ) {
		return $this->get_prop( 'tax_display_cart', $context );
	}

	/**
	 * Get Store price display suffix.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_price_display_suffix( $context = 'view' ) {
		return $this->get_prop( 'price_display_suffix', $context );
	}

	/**
	 * Get Store tax total display.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_tax_total_display( $context = 'view' ) {
		return $this->get_prop( 'tax_total_display', $context );
	}


		/**
		 * Get Store default customer.
		 *
		 * @param  string $context What the value is for. Valid values are view and edit.
		 * @return int
		 */
	public function get_default_customer( $context = 'view' ) {
		return $this->get_prop( 'default_customer', $context );
	}

	/**
	 * Get Store default customer is cashier.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return bool
	 */
	public function get_default_customer_is_cashier( $context = 'view' ) {
		return $this->get_prop( 'default_customer_is_cashier', $context );
	}

	/**
	 * Get the merchant's tracking consent: 'undecided', 'allowed' or 'denied'.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_tracking_consent( $context = 'view' ) {
		return $this->get_prop( 'tracking_consent', $context );
	}

	/**
	 * Set Pro property defaults from WooCommerce settings.
	 *
	 * These properties are fully customizable in the Pro version,
	 * but in the free version we derive sensible defaults via
	 * Store_Defaults: WCPOS general settings → WC POS core options
	 * → WordPress / WooCommerce fallbacks.
	 */
	protected function set_pro_property_defaults() {
		$this->set_prop( 'name', Store_Defaults::name() );
		$this->set_prop( 'url', \home_url() );
		$this->set_prop( 'phone', Store_Defaults::phone() );
		$this->set_prop( 'email', Store_Defaults::email() );
		$this->set_prop( 'opening_hours', array() );
		$this->set_prop( 'opening_hours_notes', '' );
		$this->set_prop( 'personal_notes', '' );
		$this->set_prop( 'policies_and_conditions', Store_Defaults::policies_and_conditions() );
		$this->set_prop( 'footer_imprint', '' );
		$this->set_prop( 'tax_ids', Store_Defaults::tax_ids() );
	}

	/**
	 * Get Store URL.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_url( $context = 'view' ) {
		return $this->get_prop( 'url', $context );
	}

	/**
	 * Get Store phone number.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_phone( $context = 'view' ) {
		return $this->get_prop( 'phone', $context );
	}

	/**
	 * Get Store email address.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_email( $context = 'view' ) {
		return $this->get_prop( 'email', $context );
	}

	/**
	 * Get Store opening hours.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return array|string
	 */
	public function get_opening_hours( $context = 'view' ) {
		return $this->get_prop( 'opening_hours', $context );
	}

	/**
	 * Get Store opening hours notes.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_opening_hours_notes( $context = 'view' ) {
		return $this->get_prop( 'opening_hours_notes', $context );
	}

	/**
	 * Get Store personal notes.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_personal_notes( $context = 'view' ) {
		return $this->get_prop( 'personal_notes', $context );
	}

	/**
	 * Get Store policies and conditions.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_policies_and_conditions( $context = 'view' ) {
		return $this->get_prop( 'policies_and_conditions', $context );
	}

	/**
	 * Get Store footer imprint.
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_footer_imprint( $context = 'view' ) {
		return $this->get_prop( 'footer_imprint', $context );
	}

	/**
	 * Get Store formatted address.
	 *
	 * @return string
	 */
	public function get_formatted_address() {
		$countries = new WC_Countries();

		return $countries->get_formatted_address(
			array(
				'address_1' => $this->get_store_address(),
				'address_2' => $this->get_store_address_2(),
				'city'      => $this->get_store_city(),
				'state'     => $this->get_store_state(),
				'postcode'  => $this->get_store_postcode(),
				'country'   => $this->get_store_country(),
			)
		);
	}

	/**
	 * Get Store tax IDs as a structured array.
	 *
	 * @param string $context What the value is for. Valid values are view and edit.
	 * @return array<int,array<string,string>>
	 */
	public function get_tax_ids( $context = 'view' ) {
		$value = $this->get_prop( 'tax_ids', $context );
		return is_array( $value ) ? $value : array();
	}

	/**
	 * Get the primary tax ID as a formatted scalar.
	 *
	 * Back-compat helper for templates using {{store.tax_id}}.
	 * Returns the first entry's value (verbatim — country prefix is preserved
	 * exactly as stored), or empty string when no entries exist.
	 *
	 * @param string $context What the value is for. Valid values are view and edit.
	 * @return string
	 */
	public function get_tax_id( $context = 'view' ) {
		$tax_ids = $this->get_tax_ids( $context );
		if ( empty( $tax_ids ) ) {
			return '';
		}
		$primary = reset( $tax_ids );
		return isset( $primary['value'] ) ? (string) $primary['value'] : '';
	}

	/**
	 * Get Store logo image source.
	 *
	 * In the free version, this returns the site's custom logo if set.
	 *
	 * @param  string $size Image size. Default 'full'.
	 * @return array|false Array of image data, or false if no image.
	 */
	public function get_logo_image_src( $size = 'full' ) {
		$custom_logo_id = \get_theme_mod( 'custom_logo' );

		if ( $custom_logo_id ) {
			return \wp_get_attachment_image_src( $custom_logo_id, $size );
		}

		return false;
	}
}

```
