public function addItem($item, $customisations = [])
    {
        $cart = $this->getCurrent();
        $stock_item = $item->FindStockItem();
        $added = false;

        if (!$item instanceof LineItem) {
            throw new ValidationException(_t(
                "ShoppingCart.WrongItemClass",
                "Item needs to be of class {class}",
                ["class" => LineItem::class]
            ));
        }

        // Start off by writing our item object (if it is
        // not in the DB)
        if (!$item->exists()) {
            $item->write();
        }

        if (!is_array($customisations)) {
            $customisations = [$customisations];
        }

        // Find any item customisation associations
        $custom_association = null;
        $custom_associations = array_merge(
            $item->hasMany(),
            $item->manyMany()
        );

        // Define association of item to customisations
        foreach ($custom_associations as $key => $value) {
            $class = $value::create();
            if ($class instanceof LineItemCustomisation) {
                $custom_association = $key;
                break;
            }
        }


        // Map any customisations to the current item
        if (isset($custom_association)) {
            $item->write();
            foreach ($customisations as $customisation) {
                if ($customisation instanceof LineItemCustomisation) {
                    if (!$customisation->exists()) {
                        $customisation->write();
                    }
                    $item->{$custom_association}()->add($customisation);
                }
            }
        }
        
        // Ensure we update the item key
        $item->write();

        // If the current cart isn't in the DB, save it
        if (!$cart->exists()) {
            $this->save();
        }

        // Check if object already in the cart, update quantity
        // and delete new item
        $existing_item = $cart->Items()->find("Key", $item->Key);

        if (isset($existing_item)) {
            $this->updateItem(
                $existing_item,
                $existing_item->Quantity + $item->Quantity
            );
            $item->delete();
            $added = true;
        }

        // If no update was sucessfull then add item
        if (!$added) {
            // If we need to track stock, do it now
            if ($stock_item && ($stock_item->Stocked || $this->config()->check_stock_levels)) {
                if ($item->checkStockLevel($item->Quantity) < 0) {
                    throw new ValidationException(_t(
                        "ShoppingCart.NotEnoughStock",
                        "There are not enough '{title}' in stock",
                        ['title' => $stock_item->Title]
                    ));
                }
            }

            $item->ParentID = $cart->ID;
            $item->write();
        }
    
        $this->save();

        return $this;
    }