# frozen_string_literal: true module Decidim # This job is used by machine translation services to store the result of # a field translation. This way services do not need to care about how to # save it and also enables storing translations asynchronously when the # translation service returns the translated text in a webhook. class MachineTranslationSaveJob < ApplicationJob queue_as :translations # Performs the job. It will not perform anything if the # `Decidim.machine_translation_service` config is not set. # # resource - Any kind of `Decidim::TranslatableResource` model instance # field_name - A Symbol representing the name of the field being translated # target_locale - A Symbol representing the target locale for the translation # translated_text - A String with the value of the field_name, translated # into the target_locale def perform(resource, field_name, target_locale, translated_text) resource.with_lock do if resource[field_name]["machine_translations"].present? resource[field_name]["machine_translations"] = resource[field_name]["machine_translations"].merge(target_locale => translated_text) else resource[field_name] = resource[field_name].merge("machine_translations" => { target_locale => translated_text }) end # rubocop:disable Rails/SkipsModelValidations resource.update_column field_name.to_sym, resource[field_name] # rubocop:enable Rails/SkipsModelValidations end send_translated_report_notifications(resource) if reported_resource_in_organization_language?(resource, target_locale) end private def send_translated_report_notifications(reportable) reportable.moderation.reports.each do |report| reportable.moderation.participatory_space.moderators.each do |moderator| Decidim::ReportedMailer.report(moderator, report).deliver_later end end end def reported_resource_in_organization_language?(resource, target_locale) return unless resource.try(:organization) resource_reported?(resource) && target_locale == resource.organization.default_locale && resource_completely_translated?(resource, target_locale) end def resource_reported?(resource) resource.class.included_modules.include?(Decidim::Reportable) && resource.reported? end def resource_completely_translated?(resource, target_locale) reported_translatable_fields = resource.reported_attributes & resource.class.translatable_fields_list reported_translatable_fields.all? do |field| resource[field]&.dig("machine_translations", target_locale).present? end end end end