<?php
/**
* Class AbstractAdditionalCost
*
* @package WPDesk\FS\TableRate\Rule\Cost
*/
namespace WPDesk\FS\TableRate\Rule\Cost;
use FSVendor\WPDesk\Forms\Renderer\JsonNormalizedRenderer;
use FSVendor\WPDesk\FS\TableRate\Settings\MethodSettings;
use JsonSerializable;
use Psr\Log\LoggerInterface;
use Throwable;
use WPDesk\FS\TableRate\Rule\Rule;
use WPDesk\FS\TableRate\Rule\ShippingContents\ShippingContents;
use function Patchwork\Config\locate;
/**
* Abstract Additional Cost.
*/
abstract class AbstractAdditionalCost implements AdditionalCost, JsonSerializable {
/**
* @var string
*/
protected $based_on;
/**
* @var string
*/
protected $name;
/**
* @var MethodSettings
*/
protected $method_settings;
/**
* @var Rule
*/
protected $rule;
/**
* @return string
*/
public function get_based_on() {
return $this->based_on;
}
/**
* @return string
*/
public function get_name() {
return $this->name;
}
/**
* @param array $additional_cost_settings .
*
* @return float|null
*/
public function get_per_value( array $additional_cost_settings ) {
$setting_value = $this->get_settings_value( RuleAdditionalCostFieldsFactory::PER_VALUE, $additional_cost_settings );
return isset( $setting_value ) ? (float) $setting_value : null;
}
/**
* @param array $additional_cost_settings .
*
* @return float|null
*/
public function get_additional_cost( array $additional_cost_settings ) {
$setting_value = $this->get_settings_value( RuleAdditionalCostFieldsFactory::ADDITIONAL_COST, $additional_cost_settings );
return isset( $setting_value ) ? (float) $setting_value : null;
}
/**
* @param string $name .
* @param array $settings .
*/
private function get_settings_value( $name, array $settings ) {
return isset( $settings[ $name ] ) ? $settings[ $name ] : null;
}
/**
* @param ShippingContents $shipping_contents .
* @param array $additional_cost_settings .
* @param LoggerInterface $logger .
*
* @return float
*/
public function calculate_cost( ShippingContents $shipping_contents, array $additional_cost_settings, LoggerInterface $logger ) {
try {
$per_value = $this->get_per_value( $additional_cost_settings );
$additional_cost = $this->get_additional_cost( $additional_cost_settings );
// Tricky fix (float->string->float) for bug in rounding (#OCT-2684).
$shipment_contents_value = (float) (string) $this->get_value_from_shipment_contents( $shipping_contents );
if ( isset( $per_value, $additional_cost ) && 0.0 !== $per_value ) {
$calculated_additional_cost = ceil( $shipment_contents_value / $per_value ) * $additional_cost;
} else {
$calculated_additional_cost = 0;
}
$logger->debug(
sprintf(
' %1$s %2$s; %3$s; %4$s; %5$s',
__( 'additional cost:', 'flexible-shipping' ),
// Translators: cost per.
sprintf( __( '%1$s per %2$s', 'flexible-shipping' ), $additional_cost, $per_value ),
// Translators: based on.
sprintf( __( 'based on: %1$s', 'flexible-shipping' ), $this->get_name() ),
// Translators: input data.
sprintf( __( 'input data: %1$s', 'flexible-shipping' ), $shipment_contents_value ),
// Translators: calculated.
sprintf( __( 'calculated: %1$s', 'flexible-shipping' ), $calculated_additional_cost )
)
);
} catch ( Throwable $e ) {
$logger->debug( $e->getMessage() );
$calculated_additional_cost = 0;
}
return $calculated_additional_cost;
}
/**
* @param ShippingContents $shipping_contents .
* @param array $additional_cost_settings .
* @param LoggerInterface $logger .
* @param MethodSettings $method_settings .
*
* @return float
*/
public function calculate_cost_with_method_settings( ShippingContents $shipping_contents, array $additional_cost_settings, LoggerInterface $logger, MethodSettings $method_settings ) {
$this->method_settings = $method_settings;
return $this->calculate_cost( $shipping_contents, $additional_cost_settings, $logger );
}
/**
* @param Rule $rule
*
* @return $this
*/
public function set_rule( Rule $rule ): AbstractAdditionalCost {
$this->rule = $rule;
return $this;
}
/**
* Returns value from shipment contents to calculate cost.
*
* @param ShippingContents $shipping_contents .
*
* @return float
*/
abstract protected function get_value_from_shipment_contents( $shipping_contents );
/**
* @return array
*/
#[\ReturnTypeWillChange]
public function jsonSerialize(): array {
$renderer = new JsonNormalizedRenderer();
return [
'additional_cost_id' => $this->get_based_on(),
'label' => $this->get_name(),
'parameters' => $renderer->render_fields( $this, [] ),
];
}
}