country = $country; parent::__construct( $location_rates ); } /** * @return string */ public function get_country(): string { return $this->country; } /** * Return collections of location rates grouped into shipping services. * * @return ServiceRatesCollection[] */ public function get_rates_grouped_by_service(): array { $this->group_rates_by_service(); return array_values( $this->services_groups ); } /** * Groups the location rates into collections of rates based on how they fit into Merchant Center services. */ protected function group_rates_by_service(): void { if ( isset( $this->services_groups ) ) { return; } $this->services_groups = []; foreach ( $this->location_rates as $location_rate ) { $country = $location_rate->get_location()->get_country(); $shipping_area = $location_rate->get_location()->get_applicable_area(); $min_order_amount = $location_rate->get_shipping_rate()->get_min_order_amount(); // Group rates by their applicable country and affecting shipping area $service_key = $country . $shipping_area; // If the rate has a min order amount constraint, then it should be under a new service if ( $location_rate->get_shipping_rate()->has_min_order_amount() ) { $service_key .= $min_order_amount; } if ( ! isset( $this->services_groups[ $service_key ] ) ) { $this->services_groups[ $service_key ] = new ServiceRatesCollection( $country, $shipping_area, $min_order_amount, [] ); } $this->services_groups[ $service_key ]->add_location_rate( $location_rate ); } } /** * @param LocationRate $location_rate * * @throws InvalidValue If any of the location rates do not belong to the same country as the one provided for this class or if any of the rates are negative. */ protected function validate_rate( LocationRate $location_rate ) { if ( $this->country !== $location_rate->get_location()->get_country() ) { throw new InvalidValue( 'All location rates must be in the same country as the one provided for this collection.' ); } if ( $location_rate->get_shipping_rate()->get_rate() < 0 ) { throw new InvalidValue( 'Shipping rates cannot be negative.' ); } } /** * Reset the internal mappings/groups */ protected function reset_rates_mappings(): void { unset( $this->services_groups ); } }