Functions - Prevent specific item from being put in chests

I built on what you had. You were very close. You mention another scoreboard objective, you do not need another.

I removed the first line from your function. (scoreboard objectives add chesthasitem dummy) You do not need to create the objective continuously. Manually type that line in chat one time to create the objective.

I added a line scoreboard players add @a chesthasitem 0. This is to make sure the stat's target is already tracked on the players scoreboard. Visit this website if you want learn more about CommandStats and why this is required. This may have been why your second scoreboard objective did not update and destroy a chest in a different direction.

The last two commands in your function I used multiple times, only editing the relative coordinates, to test 4 blocks (North, South, East, and West). You will have to add several iterations to this in order to test all possible accessible chest positions from a players position. Here is the contents of the function I was using:

#Set score for all players and set stats to record to all players
scoreboard players add @a chesthasitem 0
stats entity @a set AffectedBlocks @a chesthasitem

#Test x ~1 and destroy
execute @a ~ ~ ~ testforblock ~1 ~ ~ chest -1 {Items:[{id:"minecraft:writable_book",tag:{display:{Name:"test"}}}]} 
execute @a[score_chesthasitem_min=1] ~ ~ ~ setblock ~1 ~ ~ air 0 destroy

#Test x ~-1 and destroy
 execute @a ~ ~ ~ testforblock ~-1 ~ ~ chest -1 {Items:[{id:"minecraft:writable_book",tag:{display:{Name:"test"}}}]} 
 execute @a[score_chesthasitem_min=1] ~ ~ ~ setblock ~-1 ~ ~ air 0 destroy

#Test z ~1 and destroy
execute @a ~ ~ ~ testforblock ~ ~ ~1 chest -1 {Items:[{id:"minecraft:writable_book",tag:{display:{Name:"test"}}}]} 
execute @a[score_chesthasitem_min=1] ~ ~ ~ setblock ~ ~ ~1 air 0 destroy

#Test z ~-1 and destroy
execute @a ~ ~ ~ testforblock ~ ~ ~-1 chest -1 {Items:[{id:"minecraft:writable_book",tag:{display:{Name:"test"}}}]} 
execute @a[score_chesthasitem_min=1] ~ ~ ~ setblock ~ ~ ~-1 air 0 destroy

Note: I am detecting a Book and Quill renamed test in this example.

Then you can run the gamerule gameLoopFunction to run the function every tick. Here is the wiki on the subject. The sytax is:
/gamerule gameLoopFunction <namespace:path/to/function/file>