//Так выглядит "клиенский" код
$emailTemplate = TransactionEmailFactory::make($transaction, 'client')->render();

//Фабрика для определения того, какой емейл темплейт должен быть заюзан
abstract class TransactionEmailFactory
{
    public static function make($transaction, $target)
    {
        switch ($transaction->trans_class) {
            case 'car':
                return new CarEmail($transaction, $target);
            case 'hotel':
                return new HotelEmail($transaction, $target);
        }
    }
}

//Емейл букинга машины
class CarEmail extends TransactionEmail
{
    public $vehicleType;

    public function __construct($transaction, $target)
    {
        parent::__construct($transaction, $target);
        $this->vehicleType = $this->json_notes->vehicle;
    }
}

//Емейл букинга отеля
class HotelEmail extends TransactionEmail
{
    public $guestsInfo;

    public function __construct($transaction, $target)
    {
        parent::__construct($transaction, $targeta);
        $this->guestsInfo = $this->json_notes->guests_info;
    }
}

//Мейлабл класс для всех транзакционных емейлов
class TransactionEmail extends Mailable
{
    public $transaction;
    public $type;
    public $target;
    public $json_notes;
   
    public function __construct($transaction, $target)
    {
        $this->transaction = $transaction;
        $this->type = strtolower($transaction->trans_class);
        $this->target = $target;
        $this->json_notes = json_decode($this->transaction->notes);
    }
    
    public function build()
    {
        $target = $this->getTarget();
        $type = $this->getType();
        return $this->view("emails.transactionEmails.{$target}.{$type}");
    }
}


// ----------------------------------------------------------------------------------------------

// Дальше идут варианты реализации кастомных емейлов для определнных партнеров


class PartnerACustomization extends TransactionEmailCustomization
{   
    public function getTemplate()
    {
       	if ($this->type == 'car') {
        	return "emails.transactionEmails.custom.partnerA.car";
        } 
      
        return parent::getTemplate();
    }
}

class TransactionEmailCustomization
{   
  	public $type;
    public $target;
  
   	public function __construct($type, $target)
    {
        $this->type = $type;
        $this->target = $target;
    }
  
    public function getType()
    {
        return $this->type;
    }

    public function getTarget()
    {
        return $this->target;
    }
  
    public function getTemplate()
    {
        return "emails.transactionEmails.{$target}.{$type}";
    }
}

interface TransactionEmailsCustomizationInterface 
{
    public function getType();
    public function getTarget();
    public function getTemplate();
}

//Тогда, теоретически, класс по отправке емейлов будет выглядеть так:
class TransactionEmail extends Mailable
{
    ...
    public $customization;

    public function __construct($transaction, $target, TransactionEmailsCustomizationInterface $customization)
    {
        ...
        $this->customization = $customization;
    }

    public function build()
    {
        return $this->view($this->customization->getTemplate());
    }
}

//Ну и мы будем должны передать этот кастомизейшн класс по цепочке емейлФактори->карЕмейл->транзакшнЕмейл
abstract class TransactionEmailFactory
{
    public static function make($transaction, $target)
    {
        $customizationClass = $transaction->partner->getTransactionCustomizationClass();
        switch ($transaction->trans_class) {
            case 'car':
                return new CarEmail($transaction, $target, $customizationClass);
            case 'hotel':
                return new HotelEmail($transaction, $target, $customizationClass);
        }
    }
}

//Емейл букинга машины
class CarEmail extends TransactionEmail
{
    public $vehicleType;

    public function __construct($transaction, $target, $customizationClass)
    {
        parent::__construct($transaction, $target, $customizationClass);
        $this->vehicleType = $this->json_notes->vehicle;
    }
}

//Емейл букинга отеля
class HotelEmail extends TransactionEmail
{
    public $guestsInfo;

    public function __construct($transaction, $target, $customizationClass)
    {
        parent::__construct($transaction, $targeta, $customizationClass);
        $this->guestsInfo = $this->json_notes->guests_info;
    }
}

//И в итоге мне совсем не нравится то, что получилось :(