8 – Issue upgrading from Media Entity to Core Media module

I’ve followed the steps here to update from Media Entity to the Core Media module and I’m running into an issue.

My site does use media_entity_image so I updated that one in step 6. I ran drush mecu and everything passed fine. Ran drush updb and updates applied without error.

Once I checked out my site to make sure everything looks ok all images are now appearing as linked text with the name of the image. These images were set to “Media Image” as their display format.

At least one of my content types are throwing the following error, too:

The "entity_reference:media_image" plugin does not exist. Valid plugin IDs for Drupalentity_embedEntityEmbedDisplayEntityEmbedDisplayManager are: ...

What am I doing wrong here? Thank you!

entities – Entity where member variable is different type than when serialized

Not entirely sure how to phrase this.

I’ve got a config entity that needs to store a block id. In my config I have the mapping set to a string for the id.
When I load the entity, I’d think it would be more convenient to load the id and have the variable be a block.

This would mean I would need to :

  • On load, set $this->block = loadblock($id)
  • On save, set config->block = $block->id()

I’m finding the saving of entities to be quite ‘magic’ and thus hard for me to figure out.

Schema:

myent.myent.*:
  type: config_entity
  mapping:
    display_block:
      type: string
      label: Display block

entity:

/**
 * @ConfigEntityType(
 *   id = "myent",
 *   ...
 *   config_export = {
 *     ...
 *     "display_block",
 *   },
 * )
 */
class MyEnt extends ConfigEntityBase {

  // This should be loaded as an entity, not a string.
  protected $display_block;

}

For the loading, I could just override __construct and use the loaded string to load up the entity but that feels very hacky. Plus then IDK how to save it properly when saving.

There is also the option of having a getBlockRaw and getBlock as two seperate options. Have a variable for the string and a non exported one for the loaded entity.

entities – Confused about Entity bundles

I’m trying to convert a Drupal 7 site to Drupal 9 before D7 reaches EOL, and I had a custom module that had a lot of custom tables defined in Hook Schema, that would be joined together in different ways to handle a multi-step form made with the ctools form wizard. This site was originally created in Drupal 6, and updated to Drupal 7 while doing the minimum changes to the custom modules, so it predates the concept of Entities. The database structure of those tables is normalized, in 3rd normal form, because if you flattened it, would your end with millions of rows with mostly redundant information. The problem was that those tables existed in their own microcosm, not accessible to the rest of the site.

I’ve decided to rebuild everything from the ground up when doing the site upgrade, and I’ve also decided to drupalize this so the contents of these tables can be accessed by regular views, avoiding content duplication. This means that every old table will have to have it’s own entity type. Fields will be basefields for performance, since I will need 50-100 fields in total, and every fiend added through the UI requires a join as far as I understand. If I need to add fields in the future, I will do it through a module update, not by adding them through the UI, so I don’t need the entities to be fieldable.

After giving you this context, my actual question is, if I will only ever need 1 type of every entity bundle, do I really need entity bundles? What would entity bundles do for me?

entities – The “yourtypeentity” entity type does not exist. dans DrupalCoreEntityEntityTypeManager->getDefinition()

i have followed this tuto “https://www.droptica.com/blog/how-create-custom-entity-drupal-8/” on the web , but i am facing this error “DrupalComponentPluginExceptionPluginNotFoundException : The “dictionary_term” entity type does not exist. dans DrupalCoreEntityEntityTypeManager->getDefinition() (ligne 150 de /var/www/html/core/lib/Drupal/Core/Entity/EntityTypeManager.php).”

can anyone help me please i am new on drupal 8

<?php
/**
 * @file
 * Contains Drupalcontent_entity_exampleEntityContentEntityExample.
 */

namespace DrupaldictionaryEntity;

use DrupalCoreEntityEntityStorageInterface;
use DrupalCoreFieldBaseFieldDefinition;
use DrupalCoreEntityContentEntityBase;
use DrupalCoreEntityEntityTypeInterface;
use DrupaluserUserInterface;
use DrupalCoreEntityEntityChangedTrait;

/**
 * Defines the ContentEntityExample entity.
 *
 * @ingroup dictionary
 *
 *
 * @ContentEntityType(
 * id = "dictionary_term",
 * label = @Translation("Dictionary Term entity"),
 * handlers = {
 * "view_builder" = "DrupalCoreEntityEntityViewBuilder",
 * "list_builder" = "DrupaldictionaryEntityControllerTermListBuilder",
 * "form" = {
 * "add" = "DrupaldictionaryFormTermForm",
 * "edit" = "DrupaldictionaryFormTermForm",
 * "delete" = "DrupaldictionaryFormTermDeleteForm",
 * },
 * "access" = "DrupaldictionaryTermAccessControlHandler",
 * },
 * list_cache_contexts = { "user" },
 * base_table = "dictionary_term",
 * admin_permission = "administer dictionary_term entity",
 * entity_keys = {
 * "id" = "id",
 * "uuid" = "uuid",
 * "user_id" = "user_id",
 * "created" = "created",
 * "changed" = "changed",
 * "pl" = "pl",
 * "en" = "en",
 * },
 * links = {
 * "canonical" = "/dictionary_term/{dictionary_term}",
 * "edit-form" = "/dictionary_term/{dictionary_term}/edit",
 * "delete-form" = "/dictionary_term/{dictionary_term}/delete",
 * "collection" = "/dictionary_term/list"
 * },
 * field_ui_base_route = "entity.dictionary.term_settings",
 * )
 */
class Term extends ContentEntityBase {

  use EntityChangedTrait;

  /**
   * {@inheritdoc}
   *
   * When a new entity instance is added, set the user_id entity reference to
   * the current user as the creator of the instance.
   */
  public static function preCreate(EntityStorageInterface $storage_controller, array &$values) {
    parent::preCreate($storage_controller, $values);
// Default author to current user.
    $values += array(
      'user_id' => Drupal::currentUser()->id(),
    );
  }

  /**
   * {@inheritdoc}
   *
   * Define the field properties here.
   *
   * Field name, type and size determine the table structure.
   *
   * In addition, we can define how the field and its content can be manipulated
   * in the GUI. The behaviour of the widgets used can be determined here.
   */
  public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {

// Standard field, used as unique if primary index.
    $fields('id') = BaseFieldDefinition::create('integer')
      ->setLabel(t('ID'))
      ->setDescription(t('The ID of the Term entity.'))
      ->setReadOnly(TRUE);

// Standard field, unique outside of the scope of the current project.
    $fields('uuid') = BaseFieldDefinition::create('uuid')
      ->setLabel(t('UUID'))
      ->setDescription(t('The UUID of the Contact entity.'))
      ->setReadOnly(TRUE);

// Name field for the contact.
// We set display options for the view as well as the form.
// Users with correct privileges can change the view and edit configuration.
    $fields('pl') = BaseFieldDefinition::create('string')
      ->setLabel(t('Polish'))
      ->setDescription(t('Polish version.'))
      ->setSettings(array(
        'default_value' => '',
        'max_length' => 255,
        'text_processing' => 0,
      ))
      ->setDisplayOptions('view', array(
        'label' => 'above',
        'type' => 'string',
        'weight' => -6,
      ))
      ->setDisplayOptions('form', array(
        'type' => 'string_textfield',
        'weight' => -6,
      ))
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayConfigurable('view', TRUE);

    $fields('en') = BaseFieldDefinition::create('string')
      ->setLabel(t('English'))
      ->setDescription(t('English version.'))
      ->setSettings(array(
        'default_value' => '',
        'max_length' => 255,
        'text_processing' => 0,
      ))
      ->setDisplayOptions('view', array(
        'label' => 'above',
        'type' => 'string',
        'weight' => -4,
      ))
      ->setDisplayOptions('form', array(
        'type' => 'string_textfield',
        'weight' => -4,
      ))
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayConfigurable('view', TRUE);

// Owner field of the contact.
// Entity reference field, holds the reference to the user object.
// The view shows the user name field of the user.
// The form presents a auto complete field for the user name.
    $fields('user_id') = BaseFieldDefinition::create('entity_reference')
      ->setLabel(t('User Name'))
      ->setDescription(t('The Name of the associated user.'))
      ->setSetting('target_type', 'user')
      ->setSetting('handler', 'default')
      ->setDisplayOptions('view', array(
        'label' => 'above',
        'type' => 'author',
        'weight' => -3,
      ))
      ->setDisplayOptions('form', array(
        'type' => 'entity_reference_autocomplete',
        'settings' => array(
          'match_operator' => 'CONTAINS',
          'size' => 60,
          'placeholder' => '',
        ),
        'weight' => -3,
      ))
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayConfigurable('view', TRUE);

    $fields('created') = BaseFieldDefinition::create('created')
      ->setLabel(t('Created'))
      ->setDescription(t('The time that the entity was created.'));

    $fields('changed') = BaseFieldDefinition::create('changed')
      ->setLabel(t('Changed'))
      ->setDescription(t('The time that the entity was last edited.'));

    return $fields;
  }

}

getDefinition()" />

In which scenarios should i create a custom entity (content or config) rather than using content type?

I have always this question in mind, what are the perfect scenarios to create custom entity rather than using existing Drupal’s entities ?

entity framework – Al insertar datos en una tabla me inserta otra y me da duplicado C# EF 6 Code First

en esta oportunidad los molesto para ver si me pueden ayudar.
Estoy haciendo un desarrollo en C# Entitiy framework 6 Code First, tengo un modelo Empresa y otro Sobre,
donde una empresa puede tener muchos sobres. Lo que me pasa es que al querer insertar un sobre obtengo un error que no se pueden insertar elementos duplicados en la tabla Empresa cuando lo que yo estoy haciendo es insertar un sobre. Les dejo el código a ver si me pueen ayudar.

Modelo Sobre

public class Sobre
{
    public long id { get; set; }
    (Required)
    (MaxLength(100))
    public string fechaEmision { get; set; }
    (Required)
    public Empresa empresa { get; set; }
    (Required)
    (Index(IsUnique = true))
    public long numeroSobre { get; set; }
    (Required)
    public string nombreArchivo { get; set; }
    (Required)
    public bool enviadoDGI { get; set; }
    (MaxLength(100))
    public string fechaEnviadoDGI { get; set; }
    public string respuestaDGI { get; set; }
    public byte() archivo { get; set; }
}

Modelo empresa

public class Empresa
{
    public long Id { get; set; }
    (Required)
    (MaxLength(100))
    public string NombreComercial { get; set; }
    (Required)
    (MaxLength(12))
    (Index(IsUnique = true))
    public string Rut { get; set; }
    (Required)
    (MaxLength(100))
    public string RazonSocial { get; set; }
    (Required)
    (MaxLength(50))
    public string Telefono { get; set; }
    public string ResolucionIva { get; set; }
    public List<Sucursal> Sucursales { get; set; }
    public List<Sobre> sobres { get; set; }
}

Inserción

file = null;
                sobre1.archivo = file;
                datosEmpresa datosEmpresa = new datosEmpresa();
                Empresa empresa = new Empresa();
                oReply reply1 = new oReply();
                reply1 = datosEmpresa.BuscarEmpresaPorRut("2123132123131");

                empresa = (Empresa)reply1.Data;
                sobre1.empresa =empresa;
                sobre1.enviadoDGI = false;


                sobre1.fechaEmision = DateTime.Now.ToString();
                sobre1.nombreArchivo = "fefefefefgafheagfh";
                sobre1.numeroSobre = 27;
                sobre1.respuestaDGI = "mal";
                



                db.Sobres.Add(sobre1);
                db.SaveChanges();

Exception

An error occurred while updating the entries. See the inner exception for details.

InnerException = {“No se puede insertar una fila de clave duplicada en el objeto ‘dbo.Empresas’ con índice único ‘IX_Rut’. El valor de la clave duplicada es (2123132123131).rnSe terminó la instrucción.”}

Les agradezco si me pueden dar una mano ya que estoy trancado
Graciaaaaaaaasssssssss

performance – Entity delete validation in a microservice environment

In a microservice environment there are two services: Service A and Service B.

Service A manages an entity called x which has one to many relationship with service B’s entity called y

When a network request hits to Service A to delete a specific x, Service A makes an internal network request to service B to validate whether specific x being used with any y item.

In a microservice environment, is there a better and more efficient way to handle this kind of request and validation among two services?

Also these options already came to table, however not optimal.

  1. Managing a cache on Service A about y isn’t viable.
  2. Managing a key/property on each x about whether it’s being used or not, was
    also considered. However there’s a development overhead of migrating
    all the old data with new property.
  3. Let the front-end (webapp) directly calls Service B’s validation before hitting to delete. However there’s a possibility to have a false positive with the timing.

performance – Entity delete validation in a microservice envirenment

In a micro service environment there are two services. Service A and service B.

Service A manages an entity called x which has one to many relationship with service B’s entity called y

When a network request hits to Service A to delete a specific x, Service A makes an internal network request to service B to validate whether specific x being used with any y item.

In a micro service environment, is there a better and more efficient way to handle this kind of request and validation among two services?

Also these options already came to table, however not optimal.

  1. Managing a cache on Service A about y isn’t viable.
  2. Managing a key/property on each x about whether it’s being used or not, was
    also considered. However there’s a development overhead of migrating
    all the old data with new property.
  3. Let the front-end (webapp) directly calls Service B’s validation before hitting to delete. However there’s a possibility to have a false positive with the timing.

views – I have a ton of errors for a non-existent config entity name in dblog when I refresh cache

When I refresh my cache, my dblog is shooting out a ton of errors for the type “view”.

I received a ton of these warnings:

A non-existent config entity name returned by FieldStorageConfigInterface::getBundles(): entity type: paragraph, bundle: rs, field name: field_website

I migrated my D7 site to D8. One of the things migrated are migrating all my field_collections to paragraphs, could this be the issue?

I disabled all my custom views and the error still persists.

Any idea what could be the issue?

Thanks!

8 – Migrating content from RSS feed to populate multiple Entity reference media field

In the Drupal 8 site I’m working on, I’ve currently set up some migration configurations which import content from an external RSS feed. The file urls references in this RSS feed are imported into the site as media entities and then referenced in the generated node. All is well, except for when there are multiple file urls.

So here is the configuration for the node import:

id: rss_innovations
label: 'Import Innovations feed'
status: true

source:
  plugin: url
  data_fetcher_plugin: http
  urls: 'https://www.innovationagencyexchange.org.uk/feeds/innovations'
  data_parser_plugin: simple_xml

  item_selector: /rss/channel/item
  fields:
    -
      name: guid
      label: GUID
      selector: guid
    -
      name: title
      label: Title
      selector: title
    -
      name: pub_date
      label: 'Publication date'
      selector: pubDate
    -
      name: link
      label: 'Origin link'
      selector: link
    -
      name: description
      label: Description
      selector: 'description'
    -
      name: image
      label: Image
      selector: 'featured_image'
    -
      name: content
      label: Content
      selector: 'content'
    -
      name: organisation
      label: Organisation
      selector: 'organisation'
    -
      name: ahsnid
      label: AHSN ID
      selector: 'ahsn'
    -

  ids:
    guid:
      type: string

  constants:
    file_destination: 'public://images/'

destination:
  plugin: 'entity:node'

process:
  title: title
  field_remote_url: link
  body/value: content
  body/format:
    plugin: default_value
    default_value: basic_html
  field_ahsn: ahsnid
  field_company: organisation
  field_introduction: description
  field_image:
    plugin: image_import
    source: image
    destination: 'constants/file_destination'
    alt: !title
  uid:
    plugin: default_value
    default_value: 17
  created:
    plugin: format_date
    from_format: 'D, d M Y H:i:s O'
    to_format: 'U'
    source: pub_date
  status:
    plugin: default_value
    default_value: 1
  type:
    plugin: default_value
    default_value: innovation
  field_media:
    plugin: migration_lookup
    migration: rss_resources_files
    source: guid
    no_stub: true

migration_dependencies:
  required:
    - rss_resources_files

And here is the configuration for the file importing:

id: rss_resources_files
label: 'Import Innovation files'
status: true

source:
  plugin: url
  data_fetcher_plugin: http
  urls: 'https://www.innovationagencyexchange.org.uk/feeds/innovations'
  data_parser_plugin: simple_xml

  item_selector: /rss/channel/item
  fields:
    -
      name: guid
      label: GUID
      selector: guid
    -
      name: resourcefile
      label: Resource file
      selector: 'file'

  ids:
    guid:
      type: string

  constants:
    file_destination: 'public://resources/'

process:
  field_media_file:
    -
      plugin: skip_on_empty
      method: row
      source: resourcefile
      message: 'No file found'
    -
      plugin: explode
      source: resourcefile
      delimiter: '|'
    -
      plugin: file_import
      destination: 'constants/file_destination'
destination:
  plugin: 'entity:media'
  default_bundle: file

So these both work at the moment in terms of importing all the content and all the files. All the files are imported files as file entities (using the plugin: file_import after the explode) but then only one media entity is generated per RSS item, so only one media entity per RSS item / node. Which makes sense as the file import is running separately to the entity media generation. I guess I need to use the sub_process plugin to generate the media entities? However when I try with that it only accepts associative arrays and the array from the explode plugin does not seem to be accepted by it. If someone could point me in the right direction I’d be ever so grateful!

This is an example of the RSS feed if needed:

<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xml:base="https://www.healthinnovationexchange.org.uk/feeds/innovations" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Innovations</title>
    <link>https://www.healthinnovationexchange.org.uk/feeds/innovations</link>
    <description></description>
    <language>en</language>
     <atom:link href="https://www.healthinnovationexchange.org.uk/feeds/innovations" rel="self" type="application/rss+xml" />
      <item>
    <title>Intelligent workforce solution and indoor location technology</title>
    <link>https://www.healthinnovationexchange.org.uk/%3Ca%20href%3D%22/solutions/intelligent-workforce-solution-and-indoor-location-technology%22%3Eview%3C/a%3E</link>
    <description><!(CDATA(Many have tried to change the way clinical teams work to be more efficient; but few have focused on optimising the supporting teams that provide the logistics which underpin the flow of patients throughout the hospital.&nbsp;Navenio has done just that. By looking at the teams working within a hospital, they have proven that knowing where people are, indoors in real-time, unlocks significant improvements in their workflow and efficiency. This improves patient flow and patient care. &nbsp;))></description>
     <pubDate>Wed, 10 Jun 2020 10:29:37 +0100</pubDate>
 <dc:creator />
 <guid isPermaLink="true">https://www.healthinnovationexchange.org.uk/%3Ca%20href%3D%22/solutions/intelligent-workforce-solution-and-indoor-location-technology%22%3Eview%3C/a%3E</guid><featured_image>https://www.healthinnovationexchange.org.uk/sites/default/files/FB6E45F5-4557-4027-9517-4E48C704E6A6_1.png</featured_image>
        <content><!(CDATA(<p style="text-align:justify"><span style="font-size:12pt"><span style="font-family:Calibri,sans-serif"><span style="font-size:14.0pt"><span style="color:black">Navenio has pioneered frictionless, accurate and robust indoor location solutions, built on award-winning science from the University of Oxford – enabled simply using sensors in existing smartphones. Unlike other RTLS, RFID, Bluetooth and Wi-Fi solutions, the Navenio technology </span></span><span style="font-size:14.0pt">requires <span style="color:black">no new investment in infrastructure</span> at all; is easily scalable and accurate to within 1 to 3 metres.</span></span></span></p><p style="text-align:justify"><span style="font-size:12pt"><span style="font-family:Calibri,sans-serif"><span style="font-size:14.0pt">The Navenio solution is available in three forms:</span></span></span></p><ul><li style="text-align:justify; margin-left:8px"><span style="font-size:12pt"><span style="font-family:Calibri,sans-serif"><span style="font-size:14.0pt">Intelligent Workforce Solution (IWS)</span></span></span><ul style="list-style-type:circle"><li style="margin-left:8px; text-align:justify"><span style="font-size:12pt"><span style="font-family:Calibri,sans-serif"><span style="font-size:14.0pt">automates the prioritisation and allocation of tasks to ensure </span><span style="font-size:14.0pt">the right person is helping in the right location every time</span></span></span></li></ul></li><li style="text-align:justify; margin-left:8px"><span style="font-size:12pt"><span style="font-family:Calibri,sans-serif"><span style="font-size:14.0pt">Location only solution</span></span></span><ul style="list-style-type:circle"><li style="margin-left:8px; text-align:justify"><span style="font-size:12pt"><span style="font-family:Calibri,sans-serif"><span style="font-size:14.0pt">provides details of current and past movements of staff via their smartphones </span></span></span></li></ul></li><li style="text-align:justify; margin-left:8px"><span style="font-size:12pt"><span style="font-family:Calibri,sans-serif"><span style="font-size:14.0pt">as a fully integrated location solution that feeds into other clinical/non-clinical solutions/applications</span></span></span><ul style="list-style-type:circle"><li style="margin-left:8px; text-align:justify"><span style="font-size:12pt"><span style="font-family:Calibri,sans-serif"><span style="font-size:14.0pt">can provide valuable data to aid and improve patient consultations, discharge and referrals; and provide confirmation of where a staff member at infection risk has travelled between over a period of time</span></span></span></li></ul></li></ul>))></content>
    <organisation>Navenio Limited</organisation>
    <ahsn>2</ahsn>                                                                                                                                                                                                                                                                                     <video>https://www.navenio.com/dr-harpreet-sood</video>                        <file>https://www.healthinnovationexchange.org.uk/sites/default/files/Navenio%20Briefing%20Doc%20-%20Covid-19%20Assistance%20Briefing%20Doc%20-%2027mar20.pdf|https://www.healthinnovationexchange.org.uk/sites/default/files/AHSNsubmission%5B1%5DMT.pdf|https://www.healthinnovationexchange.org.uk/sites/default/files/Navenio%20IWS%204pp%20June%202020.pdf|https://www.healthinnovationexchange.org.uk/sites/default/files/Hospital%20Impact%20Study-MT-11.pdf</file>
</item>  
<item>
    <title>MediShout: A Logistical Brain For Healthcare </title>
    <link>https://www.healthinnovationexchange.org.uk/%3Ca%20href%3D%22/solutions/medishout-logistical-brain-healthcare%22%3Eview%3C/a%3E</link>
    <description><!(CDATA(www.MediShout.co.ukMediShout uses digital and AI technology to provide a “logistical brain” to health and social care organisations. Currently, logistical issues (e.g. faulty equipment, no PPE, broken IT, estates and facilities issues) delay staff and prevent best care. MediShout solves this problem by integrating all logistical departments onto one App, where a single-interface lets staff instantly report any non-clinical issue. Staff can track the progress of their report whilst organisations get operational oversight of all issues. AI-algorithms allows organisations to predict future problems, like broken equipment.))></description>
     <pubDate>Sat, 30 May 2020 08:32:37 +0100</pubDate>
 <dc:creator />
 <guid isPermaLink="true">https://www.healthinnovationexchange.org.uk/%3Ca%20href%3D%22/solutions/medishout-logistical-brain-healthcare%22%3Eview%3C/a%3E</guid>
        <content><!(CDATA(<p style="margin-bottom:11px"><strong>THE STORY:&nbsp;</strong><br>MediShout's founder is a surgeon and one afternoon, had to cancel three operations as a theatre lightbulb was broken. Staff had known for days but not reported it because no effective communication channels existed.</p><p style="margin-bottom:11px"><br><strong>THE HEALTHCARE PROBLEM:&nbsp;</strong><br>All clinicians are delayed daily by similar problems because healthcare buildings are poorly automated and not digitally connective. Staff get delayed by logistical and infra-structure problems e.g. forgotten passwords, broken equipment, low stock, lack of PPE.</p><p style="margin-bottom:11px"><br><strong>THE IMPACT IS HUGE:&nbsp;</strong><br>1. Journal of Nursing Times reported a third of NHS Nurses waste two hours per shift looking for equipment, costing the NHS almost £1billion annually.<br>2. There's been a 32% increase in cancelled NHS procedures due to equipment and staffing issues</p><p style="margin-bottom:11px"><br><strong>THE SOLUTION:&nbsp;</strong><br>MediShout is on the NHS Innovation Accelerator and provides the first platform in healthcare to integrate all logistical departments e.g. IT, estates, facilities, stock, equipment, suppliers. The MediShout App provides a single-interface for staff to instantly report any non-clinical issue. Staff can track the progress of their report whilst organisations get operational oversight and can see what issues are most impacting patient care and need fixing first. Artificial intelligence (AI) allows organisations to predict future problems, like broken equipment.</p><p style="margin-bottom:11px"><br><strong>BENEFITS:&nbsp;</strong><br>Health economists have shown MediShout can save NHS Trusts £1million annually (see attached report) and save 15 minutes per clinician daily. By sending staff reports directly to equipment suppliers, MediShout can improve output of surgical theatres and endoscopy departments.</p>))></content>
    <organisation>MediShout</organisation>
    <ahsn>2</ahsn>                                                                      <file>https://www.healthinnovationexchange.org.uk/sites/default/files/MediShout%20-%20Health%20Economic%20Impact%20Report%20%28HEE%29.pdf</file>
          </item>  </channel>
</rss>