PluginProbe
WCPOS – Point of Sale (POS) plugin for WooCommerce / 1.10.3
WCPOS – Point of Sale (POS) plugin for WooCommerce v1.10.3
1.10.19 1.10.18 1.10.17 1.10.16 1.10.15 1.10.13 1.10.14 1.10.12 1.10.11 1.10.10 1.10.9 1.10.8 untagged-3d9b7ccddc54df87c672 1.10.7 1.10.6 1.10.5 1.10.3 1.10.4 1.10.2 1.10.1 1.10.0 1.9.17 1.9.15 1.9.16 1.9.14 All 163 releases
woocommerce-pos / includes / Abstracts / Store.php

Store.php in WCPOS – Point of Sale (POS) plugin for WooCommerce 1.10.3, at includes/Abstracts/Store.php

665 lines 20.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Abstract Store class.
4 *
5 * @package WooCommerce\POS\Abstracts
6 */
7
8 namespace WCPOS\WooCommercePOS\Abstracts;
9
10 use WCPOS\WooCommercePOS\Interfaces\StoreInterface;
11 use WCPOS\WooCommercePOS\Services\Receipt_I18n_Labels;
12 use WCPOS\WooCommercePOS\Services\Settings;
13 use WCPOS\WooCommercePOS\Services\Store_Defaults;
14 use WC_Countries;
15 use function wc_format_country_state_string;
16
17 if ( ! defined( 'ABSPATH' ) ) {
18 exit;
19 }
20
21 /**
22 * Abstract Store class.
23 *
24 * Handles the store data, and provides CRUD methods.
25 * Implements StoreInterface to ensure API consistency with Pro version.
26 */
27 class Store extends \WC_Data implements StoreInterface {
28 /**
29 * This is the name of this object type.
30 *
31 * @var string
32 */
33 protected $object_type = 'store';
34
35 /**
36 * Stores product data.
37 *
38 * @var array
39 */
40 protected $data = array(
41 'name' => '',
42 'locale' => '',
43 'timezone' => '',
44 'store_address' => '',
45 'store_address_2' => '',
46 'store_city' => '',
47 'store_postcode' => '',
48 'store_state' => '',
49 'store_country' => '',
50 'default_customer_address' => '',
51 'calc_taxes' => '',
52 'enable_coupons' => '',
53 'calc_discounts_sequentially' => '',
54 'currency' => '',
55 'currency_pos' => '',
56 'price_thousand_sep' => '',
57 'price_decimal_sep' => '',
58 'price_num_decimals' => '',
59 'prevent_overselling' => false,
60 'prices_include_tax' => '',
61 'tax_based_on' => '',
62 'tax_address' => array(
63 'country' => '',
64 'state' => '',
65 'postcode' => '',
66 'city' => '',
67 ),
68 'shipping_tax_class' => '',
69 'tax_round_at_subtotal' => '',
70 'tax_display_shop' => '',
71 'tax_display_cart' => '',
72 'price_display_suffix' => '',
73 'tax_total_display' => '',
74 'default_customer' => 0,
75 'default_customer_is_cashier' => false,
76 // Pro properties (with WooCommerce defaults in free version).
77 'url' => '',
78 'phone' => '',
79 'email' => '',
80 'opening_hours' => array(),
81 'opening_hours_notes' => '',
82 'personal_notes' => '',
83 'policies_and_conditions' => '',
84 'footer_imprint' => '',
85 'tax_ids' => array(),
86 );
87
88 /**
89 * Construct the default POS store.
90 */
91 public function __construct() {
92 parent::__construct();
93 $this->set_wordpress_settings();
94 $this->set_woocommerce_general_settings();
95 $this->set_woocommerce_tax_settings();
96 $this->set_woocommerce_pos_settings();
97 $this->set_pro_property_defaults();
98 }
99
100 /**
101 * Set WordPress settings.
102 */
103 public function set_wordpress_settings() {
104 $this->set_prop( 'locale', \get_locale() );
105 $this->set_prop( 'timezone', \wp_timezone_string() );
106 }
107
108 /**
109 * Set WooCommerce general settings.
110 */
111 public function set_woocommerce_general_settings() {
112 $default_country = \WC_Admin_Settings::get_option( 'woocommerce_default_country' );
113 $country_state_array = wc_format_country_state_string( $default_country );
114
115 $this->set_prop( 'store_address', \WC_Admin_Settings::get_option( 'woocommerce_store_address' ) );
116 $this->set_prop( 'store_address_2', \WC_Admin_Settings::get_option( 'woocommerce_store_address_2' ) );
117 $this->set_prop( 'store_city', \WC_Admin_Settings::get_option( 'woocommerce_store_city' ) );
118 $this->set_prop( 'store_state', $country_state_array['state'] );
119 $this->set_prop( 'store_country', $country_state_array['country'] );
120 // $this->set_prop( 'default_country', $default_country );
121 $this->set_prop( 'store_postcode', \WC_Admin_Settings::get_option( 'woocommerce_store_postcode' ) );
122 $this->set_prop( 'default_customer_address', \WC_Admin_Settings::get_option( 'woocommerce_default_customer_address' ) );
123 $this->set_prop( 'calc_taxes', \WC_Admin_Settings::get_option( 'woocommerce_calc_taxes' ) );
124 $this->set_prop( 'enable_coupons', \WC_Admin_Settings::get_option( 'woocommerce_enable_coupons' ) );
125 $this->set_prop( 'calc_discounts_sequentially', \WC_Admin_Settings::get_option( 'woocommerce_calc_discounts_sequentially' ) );
126 $this->set_prop( 'currency', \WC_Admin_Settings::get_option( 'woocommerce_currency' ) );
127 $this->set_prop( 'currency_pos', \WC_Admin_Settings::get_option( 'woocommerce_currency_pos' ) );
128 $this->set_prop( 'price_thousand_sep', \WC_Admin_Settings::get_option( 'woocommerce_price_thousand_sep' ) );
129 $this->set_prop( 'price_decimal_sep', \WC_Admin_Settings::get_option( 'woocommerce_price_decimal_sep' ) );
130 $this->set_prop( 'price_num_decimals', (int) \WC_Admin_Settings::get_option( 'woocommerce_price_num_decimals', 2 ) );
131 }
132
133 /**
134 * Set WooCommerce tax settings.
135 */
136 public function set_woocommerce_tax_settings() {
137 $this->set_prop( 'prices_include_tax', \WC_Admin_Settings::get_option( 'woocommerce_prices_include_tax' ) );
138 $this->set_prop( 'tax_based_on', 'base' ); // default should be base, perhaps have a setting for this?
139 $this->set_prop( 'shipping_tax_class', \WC_Admin_Settings::get_option( 'woocommerce_shipping_tax_class' ) );
140 $this->set_prop( 'tax_round_at_subtotal', \WC_Admin_Settings::get_option( 'woocommerce_tax_round_at_subtotal' ) );
141 $this->set_prop( 'tax_display_shop', \WC_Admin_Settings::get_option( 'woocommerce_tax_display_shop' ) );
142 $this->set_prop( 'tax_display_cart', \WC_Admin_Settings::get_option( 'woocommerce_tax_display_cart' ) );
143 $this->set_prop( 'price_display_suffix', \WC_Admin_Settings::get_option( 'woocommerce_price_display_suffix' ) );
144 $this->set_prop( 'tax_total_display', \WC_Admin_Settings::get_option( 'woocommerce_tax_total_display' ) );
145
146 // tax address is same as WooCommerce address by default.
147 $country_state_array = wc_format_country_state_string( \WC_Admin_Settings::get_option( 'woocommerce_default_country' ) );
148
149 $this->set_prop(
150 'tax_address',
151 array(
152 'country' => $country_state_array['country'],
153 'state' => $country_state_array['state'],
154 'postcode' => \WC_Admin_Settings::get_option( 'woocommerce_store_postcode' ),
155 'city' => \WC_Admin_Settings::get_option( 'woocommerce_store_city' ),
156 )
157 );
158 }
159
160 /**
161 * Set WooCommerce POS settings.
162 */
163 public function set_woocommerce_pos_settings() {
164 $this->set_prop( 'default_customer', Settings::instance()->default_customer_id() );
165 $this->set_prop( 'default_customer_is_cashier', Settings::instance()->default_customer_is_cashier() );
166 $this->set_prop( 'prevent_overselling', Settings::instance()->prevent_overselling_enabled() );
167 }
168
169 /**
170 * Get the store data as an array.
171 *
172 * Extends the raw prop data with `receipt_i18n`, the receipt label
173 * dictionary resolved for this store's locale. The client persists it on
174 * the store record so offline/fallback receipt renders use the same
175 * translated labels as server-built receipt payloads (issue mono#1252).
176 * Computed here (not stored as a prop) so Pro's per-outlet locale
177 * override is applied before resolution.
178 *
179 * @return array
180 */
181 public function get_data() {
182 $data = parent::get_data();
183 $data['receipt_i18n'] = Receipt_I18n_Labels::get_labels( (string) $this->get_locale() );
184
185 return $data;
186 }
187
188 /**
189 * Get Store name.
190 *
191 * @param string $context What the value is for. Valid values are view and edit.
192 * @return string
193 */
194 public function get_name( $context = 'view' ) {
195 return $this->get_prop( 'name', $context );
196 }
197
198 /**
199 * Get Store locale.
200 *
201 * @param string $context What the value is for. Valid values are view and edit.
202 * @return string
203 */
204 public function get_locale( $context = 'view' ) {
205 return $this->get_prop( 'locale', $context );
206 }
207
208
209 /**
210 * Get Store timezone.
211 *
212 * Empty string means inherit the WordPress site timezone.
213 *
214 * @param string $context What the value is for. Valid values are view and edit.
215 * @return string
216 */
217 public function get_timezone( $context = 'view' ) {
218 $value = $this->get_prop( 'timezone', $context );
219 return is_string( $value ) ? $value : '';
220 }
221
222 /**
223 * Get Store address.
224 *
225 * @param string $context What the value is for. Valid values are view and edit.
226 * @return string
227 */
228 public function get_store_address( $context = 'view' ) {
229 return $this->get_prop( 'store_address', $context );
230 }
231
232 /**
233 * Get Store address 2.
234 *
235 * @param string $context What the value is for. Valid values are view and edit.
236 * @return string
237 */
238 public function get_store_address_2( $context = 'view' ) {
239 return $this->get_prop( 'store_address_2', $context );
240 }
241
242 /**
243 * Get Store city.
244 *
245 * @param string $context What the value is for. Valid values are view and edit.
246 * @return string
247 */
248 public function get_store_city( $context = 'view' ) {
249 return $this->get_prop( 'store_city', $context );
250 }
251
252 /**
253 * Get Store postcode.
254 *
255 * @param string $context What the value is for. Valid values are view and edit.
256 * @return string
257 */
258 public function get_store_postcode( $context = 'view' ) {
259 return $this->get_prop( 'store_postcode', $context );
260 }
261
262 /**
263 * Get Store country, eg: US:AL.
264 * This is of the form COUNTRYCODE:STATECODE to be consistent with the WooCommerce settings.
265 *
266 * @param string $context What the value is for. Valid values are view and edit.
267 * @return string
268 */
269 // phpcs:disable Squiz.Commenting.InlineComment.InvalidEndChar -- Commented-out code.
270 // public function get_default_country( $context = 'view' ) {
271 // return $this->get_prop( 'default_country', $context );
272 // }
273 // phpcs:enable Squiz.Commenting.InlineComment.InvalidEndChar
274
275 /**
276 * Get Store state code.
277 *
278 * @param string $context What the value is for. Valid values are view and edit.
279 * @return string
280 */
281 public function get_store_state( $context = 'view' ) {
282 return $this->get_prop( 'store_state', $context );
283 }
284
285 /**
286 * Get Store country code.
287 *
288 * @param string $context What the value is for. Valid values are view and edit.
289 * @return string
290 */
291 public function get_store_country( $context = 'view' ) {
292 return $this->get_prop( 'store_country', $context );
293 }
294
295 /**
296 * Get Store customer address.
297 *
298 * @param string $context What the value is for. Valid values are view and edit.
299 * @return string
300 */
301 public function get_default_customer_address( $context = 'view' ) {
302 return $this->get_prop( 'default_customer_address', $context );
303 }
304
305 /**
306 * Get Store calculate taxes.
307 *
308 * @param string $context What the value is for. Valid values are view and edit.
309 * @return string
310 */
311 public function get_calc_taxes( $context = 'view' ) {
312 return $this->get_prop( 'calc_taxes', $context );
313 }
314
315 /**
316 * Get Store enable coupons.
317 *
318 * @param string $context What the value is for. Valid values are view and edit.
319 * @return string
320 */
321 public function get_enable_coupons( $context = 'view' ) {
322 return $this->get_prop( 'enable_coupons', $context );
323 }
324
325 /**
326 * Get Store calculate discounts sequentially.
327 *
328 * @param string $context What the value is for. Valid values are view and edit.
329 * @return string
330 */
331 public function get_calc_discounts_sequentially( $context = 'view' ) {
332 return $this->get_prop( 'calc_discounts_sequentially', $context );
333 }
334
335 /**
336 * Get Store currency.
337 *
338 * @param string $context What the value is for. Valid values are view and edit.
339 * @return string
340 */
341 public function get_currency( $context = 'view' ) {
342 return $this->get_prop( 'currency', $context );
343 }
344
345 /**
346 * Get Store currency position.
347 *
348 * @param string $context What the value is for. Valid values are view and edit.
349 * @return string
350 */
351 public function get_currency_position( $context = 'view' ) {
352 return $this->get_prop( 'currency_pos', $context );
353 }
354
355 /**
356 * Get Store price thousand separator.
357 *
358 * @param string $context What the value is for. Valid values are view and edit.
359 * @return string
360 */
361 public function get_price_thousand_separator( $context = 'view' ) {
362 return $this->get_prop( 'price_thousand_sep', $context );
363 }
364
365 /**
366 * Get Store price decimal separator.
367 *
368 * @param string $context What the value is for. Valid values are view and edit.
369 * @return string
370 */
371 public function get_price_decimal_separator( $context = 'view' ) {
372 return $this->get_prop( 'price_decimal_sep', $context );
373 }
374
375 /**
376 * Get Store price number of decimals.
377 *
378 * @param string $context What the value is for. Valid values are view and edit.
379 * @return int
380 */
381 public function get_price_number_of_decimals( $context = 'view' ) {
382 return $this->get_prop( 'price_num_decimals', $context );
383 }
384
385 /**
386 * Get Store prices include tax.
387 *
388 * @param string $context What the value is for. Valid values are view and edit.
389 * @return string
390 */
391 public function get_prices_include_tax( $context = 'view' ) {
392 return $this->get_prop( 'prices_include_tax', $context );
393 }
394
395 /**
396 * Get Store tax based on.
397 *
398 * @param string $context What the value is for. Valid values are view and edit.
399 * @return string
400 */
401 public function get_tax_based_on( $context = 'view' ) {
402 return $this->get_prop( 'tax_based_on', $context );
403 }
404
405 /**
406 * Get Store tax address.
407 *
408 * @param string $context What the value is for. Valid values are view and edit.
409 * @return array
410 */
411 public function get_tax_address( $context = 'view' ) {
412 return $this->get_prop( 'tax_address', $context );
413 }
414
415 /**
416 * Get Store shipping tax class.
417 *
418 * @param string $context What the value is for. Valid values are view and edit.
419 * @return string
420 */
421 public function get_shipping_tax_class( $context = 'view' ) {
422 return $this->get_prop( 'shipping_tax_class', $context );
423 }
424
425 /**
426 * Get Store tax round at subtotal.
427 *
428 * @param string $context What the value is for. Valid values are view and edit.
429 * @return string
430 */
431 public function get_tax_round_at_subtotal( $context = 'view' ) {
432 return $this->get_prop( 'tax_round_at_subtotal', $context );
433 }
434
435 /**
436 * Get Store tax display shop.
437 *
438 * @param string $context What the value is for. Valid values are view and edit.
439 * @return string
440 */
441 public function get_tax_display_shop( $context = 'view' ) {
442 return $this->get_prop( 'tax_display_shop', $context );
443 }
444
445 /**
446 * Get Store tax display cart.
447 *
448 * @param string $context What the value is for. Valid values are view and edit.
449 * @return string
450 */
451 public function get_tax_display_cart( $context = 'view' ) {
452 return $this->get_prop( 'tax_display_cart', $context );
453 }
454
455 /**
456 * Get Store price display suffix.
457 *
458 * @param string $context What the value is for. Valid values are view and edit.
459 * @return string
460 */
461 public function get_price_display_suffix( $context = 'view' ) {
462 return $this->get_prop( 'price_display_suffix', $context );
463 }
464
465 /**
466 * Get Store tax total display.
467 *
468 * @param string $context What the value is for. Valid values are view and edit.
469 * @return string
470 */
471 public function get_tax_total_display( $context = 'view' ) {
472 return $this->get_prop( 'tax_total_display', $context );
473 }
474
475
476 /**
477 * Get Store default customer.
478 *
479 * @param string $context What the value is for. Valid values are view and edit.
480 * @return int
481 */
482 public function get_default_customer( $context = 'view' ) {
483 return $this->get_prop( 'default_customer', $context );
484 }
485
486 /**
487 * Get Store default customer is cashier.
488 *
489 * @param string $context What the value is for. Valid values are view and edit.
490 * @return bool
491 */
492 public function get_default_customer_is_cashier( $context = 'view' ) {
493 return $this->get_prop( 'default_customer_is_cashier', $context );
494 }
495
496 /**
497 * Set Pro property defaults from WooCommerce settings.
498 *
499 * These properties are fully customizable in the Pro version,
500 * but in the free version we derive sensible defaults via
501 * Store_Defaults: WCPOS general settings → WC POS core options
502 * → WordPress / WooCommerce fallbacks.
503 */
504 protected function set_pro_property_defaults() {
505 $this->set_prop( 'name', Store_Defaults::name() );
506 $this->set_prop( 'url', \home_url() );
507 $this->set_prop( 'phone', Store_Defaults::phone() );
508 $this->set_prop( 'email', Store_Defaults::email() );
509 $this->set_prop( 'opening_hours', array() );
510 $this->set_prop( 'opening_hours_notes', '' );
511 $this->set_prop( 'personal_notes', '' );
512 $this->set_prop( 'policies_and_conditions', Store_Defaults::policies_and_conditions() );
513 $this->set_prop( 'footer_imprint', '' );
514 $this->set_prop( 'tax_ids', Store_Defaults::tax_ids() );
515 }
516
517 /**
518 * Get Store URL.
519 *
520 * @param string $context What the value is for. Valid values are view and edit.
521 * @return string
522 */
523 public function get_url( $context = 'view' ) {
524 return $this->get_prop( 'url', $context );
525 }
526
527 /**
528 * Get Store phone number.
529 *
530 * @param string $context What the value is for. Valid values are view and edit.
531 * @return string
532 */
533 public function get_phone( $context = 'view' ) {
534 return $this->get_prop( 'phone', $context );
535 }
536
537 /**
538 * Get Store email address.
539 *
540 * @param string $context What the value is for. Valid values are view and edit.
541 * @return string
542 */
543 public function get_email( $context = 'view' ) {
544 return $this->get_prop( 'email', $context );
545 }
546
547 /**
548 * Get Store opening hours.
549 *
550 * @param string $context What the value is for. Valid values are view and edit.
551 * @return array|string
552 */
553 public function get_opening_hours( $context = 'view' ) {
554 return $this->get_prop( 'opening_hours', $context );
555 }
556
557 /**
558 * Get Store opening hours notes.
559 *
560 * @param string $context What the value is for. Valid values are view and edit.
561 * @return string
562 */
563 public function get_opening_hours_notes( $context = 'view' ) {
564 return $this->get_prop( 'opening_hours_notes', $context );
565 }
566
567 /**
568 * Get Store personal notes.
569 *
570 * @param string $context What the value is for. Valid values are view and edit.
571 * @return string
572 */
573 public function get_personal_notes( $context = 'view' ) {
574 return $this->get_prop( 'personal_notes', $context );
575 }
576
577 /**
578 * Get Store policies and conditions.
579 *
580 * @param string $context What the value is for. Valid values are view and edit.
581 * @return string
582 */
583 public function get_policies_and_conditions( $context = 'view' ) {
584 return $this->get_prop( 'policies_and_conditions', $context );
585 }
586
587 /**
588 * Get Store footer imprint.
589 *
590 * @param string $context What the value is for. Valid values are view and edit.
591 * @return string
592 */
593 public function get_footer_imprint( $context = 'view' ) {
594 return $this->get_prop( 'footer_imprint', $context );
595 }
596
597 /**
598 * Get Store formatted address.
599 *
600 * @return string
601 */
602 public function get_formatted_address() {
603 $countries = new WC_Countries();
604
605 return $countries->get_formatted_address(
606 array(
607 'address_1' => $this->get_store_address(),
608 'address_2' => $this->get_store_address_2(),
609 'city' => $this->get_store_city(),
610 'state' => $this->get_store_state(),
611 'postcode' => $this->get_store_postcode(),
612 'country' => $this->get_store_country(),
613 )
614 );
615 }
616
617 /**
618 * Get Store tax IDs as a structured array.
619 *
620 * @param string $context What the value is for. Valid values are view and edit.
621 * @return array<int,array<string,string>>
622 */
623 public function get_tax_ids( $context = 'view' ) {
624 $value = $this->get_prop( 'tax_ids', $context );
625 return is_array( $value ) ? $value : array();
626 }
627
628 /**
629 * Get the primary tax ID as a formatted scalar.
630 *
631 * Back-compat helper for templates using {{store.tax_id}}.
632 * Returns the first entry's value (verbatim — country prefix is preserved
633 * exactly as stored), or empty string when no entries exist.
634 *
635 * @param string $context What the value is for. Valid values are view and edit.
636 * @return string
637 */
638 public function get_tax_id( $context = 'view' ) {
639 $tax_ids = $this->get_tax_ids( $context );
640 if ( empty( $tax_ids ) ) {
641 return '';
642 }
643 $primary = reset( $tax_ids );
644 return isset( $primary['value'] ) ? (string) $primary['value'] : '';
645 }
646
647 /**
648 * Get Store logo image source.
649 *
650 * In the free version, this returns the site's custom logo if set.
651 *
652 * @param string $size Image size. Default 'full'.
653 * @return array|false Array of image data, or false if no image.
654 */
655 public function get_logo_image_src( $size = 'full' ) {
656 $custom_logo_id = \get_theme_mod( 'custom_logo' );
657
658 if ( $custom_logo_id ) {
659 return \wp_get_attachment_image_src( $custom_logo_id, $size );
660 }
661
662 return false;
663 }
664 }
665