diff --git a/Brewfile b/Brewfile index c9218a3e..c505240f 100644 --- a/Brewfile +++ b/Brewfile @@ -38,3 +38,6 @@ brew "tfenv" # AWS command-line utilities necessary for deploying and operations brew "awscli" cask "session-manager-plugin" + +# necessary for file encryption +brew "gpg" diff --git a/app/Gemfile b/app/Gemfile index e93a71c6..505ed01c 100644 --- a/app/Gemfile +++ b/app/Gemfile @@ -14,7 +14,7 @@ gem "sprockets-rails" gem "pg", "~> 1.1" # Use the Puma web server [https://github.com/puma/puma] -gem "puma", "~> 5.0" +gem "puma", "~> 6.4.3" # Bundle and transpile JavaScript [https://github.com/rails/jsbundling-rails] gem "jsbundling-rails" diff --git a/app/Gemfile.lock b/app/Gemfile.lock index 394c48f9..edc8376e 100644 --- a/app/Gemfile.lock +++ b/app/Gemfile.lock @@ -328,7 +328,7 @@ GEM psych (5.1.2) stringio public_suffix (6.0.1) - puma (5.6.8) + puma (6.4.3) nio4r (~> 2.0) racc (1.8.1) rack (2.2.9) @@ -510,7 +510,7 @@ GEM addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) - webrick (1.8.1) + webrick (1.8.2) websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) @@ -557,7 +557,7 @@ DEPENDENCIES pg (~> 1.1) pg-aws_rds_iam (~> 0.5.0) premailer-rails - puma (~> 5.0) + puma (~> 6.4.3) rails (~> 7.1.3, >= 7.1.3.4) rails-controller-testing rails-erd (~> 1.7) diff --git a/app/app/components/pinwheel_data_point_component.html.erb b/app/app/components/pinwheel_data_point_component.html.erb index 8d812947..47cddef6 100644 --- a/app/app/components/pinwheel_data_point_component.html.erb +++ b/app/app/components/pinwheel_data_point_component.html.erb @@ -1 +1 @@ -<%= render(TableRowComponent.new(label: @field[:label], value: @field[:value], highlight: @highlight)) %> +<%= render(TableRowComponent.new(@field[:label], @field[:value], highlight: @highlight)) %> diff --git a/app/app/components/table_row_component.html.erb b/app/app/components/table_row_component.html.erb index f1096eb0..055bf68c 100644 --- a/app/app/components/table_row_component.html.erb +++ b/app/app/components/table_row_component.html.erb @@ -1,4 +1,5 @@ "> - <%= @label %> - <%= @value %> + <% @cells.each do |cell| %> + <%= cell %> + <% end %> diff --git a/app/app/components/table_row_component.rb b/app/app/components/table_row_component.rb index e244e321..0a65983d 100644 --- a/app/app/components/table_row_component.rb +++ b/app/app/components/table_row_component.rb @@ -1,9 +1,8 @@ # frozen_string_literal: true class TableRowComponent < ViewComponent::Base - def initialize(label:, value:, highlight: false) - @label = label - @value = value + def initialize(*cells, highlight: false) + @cells = cells @highlight = highlight end end diff --git a/app/app/controllers/caseworker/cbv_flow_invitations_controller.rb b/app/app/controllers/caseworker/cbv_flow_invitations_controller.rb index 74ae294b..aa141d33 100644 --- a/app/app/controllers/caseworker/cbv_flow_invitations_controller.rb +++ b/app/app/controllers/caseworker/cbv_flow_invitations_controller.rb @@ -27,7 +27,7 @@ def create if @cbv_flow_invitation.errors.any? error_count = @cbv_flow_invitation.errors.size - error_header = "#{"error".pluralize(error_count)} occurred" + error_header = "#{helpers.pluralize(error_count, 'error')} occurred" # Collect error messages without attribute names error_messages = @cbv_flow_invitation.errors.messages.values.flatten.map { |msg| "
  • #{msg}
  • " }.join diff --git a/app/app/controllers/cbv/summaries_controller.rb b/app/app/controllers/cbv/summaries_controller.rb index ff35dc35..fd12ba58 100644 --- a/app/app/controllers/cbv/summaries_controller.rb +++ b/app/app/controllers/cbv/summaries_controller.rb @@ -27,7 +27,10 @@ def show cbv_flow_id: @cbv_flow.id }) - render pdf: "#{@cbv_flow.id}", layout: "pdf", locals: { is_caseworker: false }, footer: { right: "Income Verification Report | Page [page] of [topage]", font_size: 10 } + render pdf: "#{@cbv_flow.id}", + layout: "pdf", + locals: { is_caseworker: Rails.env.development? && params[:is_caseworker] }, + footer: { right: "Income Verification Report | Page [page] of [topage]", font_size: 10 } end end end @@ -100,6 +103,7 @@ def transmit_to_caseworker # Generate PDF pdf_service = PdfService.new @pdf_output = pdf_service.generate( + renderer: self, template: "cbv/summaries/show", variables: { is_caseworker: true, @@ -108,7 +112,7 @@ def transmit_to_caseworker employments: @employments, incomes: @incomes, identities: @identities, - payments_grouped_by_employer: summarize_by_employer(@payments, @employments, @incomes, @identities), + payments_grouped_by_employer: summarize_by_employer(@payments, @employments, @incomes, @identities, @cbv_flow.pinwheel_accounts), has_consent: has_consent } ) diff --git a/app/app/controllers/concerns/cbv/reports_helper.rb b/app/app/controllers/concerns/cbv/reports_helper.rb index 5fdb68e2..2dcd6ed8 100644 --- a/app/app/controllers/concerns/cbv/reports_helper.rb +++ b/app/app/controllers/concerns/cbv/reports_helper.rb @@ -4,7 +4,7 @@ module Cbv::ReportsHelper include Cbv::PaymentsHelper def payments_grouped_by_employer - summarize_by_employer(@payments, @employments, @incomes, @identities) + summarize_by_employer(@payments, @employments, @incomes, @identities, @cbv_flow.pinwheel_accounts) end def set_employments(account_id = nil) @@ -23,17 +23,17 @@ def total_gross_income @payments.reduce(0) { |sum, payment| sum + payment[:gross_pay_amount] } end - def summarize_by_employer(payments, employments, incomes, identities) - payments - .each_with_object({}) do |payment, hash| - account_id = payment[:account_id] - pinwheel_account = PinwheelAccount.find_by_pinwheel_account_id(account_id) + def summarize_by_employer(payments, employments, incomes, identities, pinwheel_accounts) + pinwheel_accounts + .each_with_object({}) do |pinwheel_account, hash| + account_id = pinwheel_account.pinwheel_account_id has_income_data = pinwheel_account.job_succeeded?("income") has_employment_data = pinwheel_account.job_succeeded?("employment") has_identity_data = pinwheel_account.job_succeeded?("identity") + account_payments = payments.filter { |payment| payment[:account_id] == account_id } hash[account_id] ||= { - total: 0, - payments: [], + total: account_payments.sum { |payment| payment[:gross_pay_amount] }, + payments: account_payments, has_income_data: has_income_data, has_employment_data: has_employment_data, has_identity_data: has_identity_data, @@ -41,8 +41,6 @@ def summarize_by_employer(payments, employments, incomes, identities) employment: has_employment_data && employments.find { |employment| employment["account_id"] == account_id }, identity: has_identity_data && identities.find { |identity| identity["account_id"] == account_id } } - hash[account_id][:total] += payment[:gross_pay_amount] - hash[account_id][:payments] << payment end end diff --git a/app/app/controllers/webhooks/pinwheel/events_controller.rb b/app/app/controllers/webhooks/pinwheel/events_controller.rb index 4262014b..c2bd4122 100644 --- a/app/app/controllers/webhooks/pinwheel/events_controller.rb +++ b/app/app/controllers/webhooks/pinwheel/events_controller.rb @@ -15,6 +15,7 @@ def create PinwheelAccount .create_with(cbv_flow: @cbv_flow, supported_jobs: supported_jobs) .find_or_create_by(pinwheel_account_id: params["payload"]["account_id"]) + track_account_created_event(@cbv_flow, params["payload"]["platform_name"]) end if PinwheelAccount::EVENTS_MAP.keys.include?(params["event"]) @@ -26,6 +27,8 @@ def create end if pinwheel_account.has_fully_synced? + track_account_synced_event(@cbv_flow, pinwheel_account) + PaystubsChannel.broadcast_to(@cbv_flow, { event: "cbv.payroll_data_available", account_id: params["payload"]["account_id"] @@ -50,6 +53,30 @@ def authorize_webhook end end + def track_account_synced_event(cbv_flow, pinwheel_account) + NewRelicEventTracker.track("PinwheelAccountSyncFinished", { + cbv_flow_id: cbv_flow.id, + identity_success: pinwheel_account.job_succeeded?("identity"), + identity_supported: pinwheel_account.supported_jobs.include?("identity"), + income_success: pinwheel_account.job_succeeded?("income"), + income_supported: pinwheel_account.supported_jobs.include?("income"), + paystubs_success: pinwheel_account.job_succeeded?("paystubs"), + paystubs_supported: pinwheel_account.supported_jobs.include?("paystubs"), + employment_success: pinwheel_account.job_succeeded?("employment"), + employment_supported: pinwheel_account.supported_jobs.include?("employment"), + sync_duration_seconds: Time.now - pinwheel_account.created_at + }) + rescue => ex + Rails.logger.error "Unable to track NewRelic event (PinwheelAccountSyncFinished): #{ex}" + end + + def track_account_created_event(cbv_flow, platform_name) + NewRelicEventTracker.track("PinwheelAccountCreated", { + cbv_flow_id: cbv_flow.id, + platform_name: platform_name + }) + end + def set_cbv_flow @cbv_flow = CbvFlow.find_by_pinwheel_end_user_id(params["payload"]["end_user_id"]) end diff --git a/app/app/models/cbv_flow_invitation.rb b/app/app/models/cbv_flow_invitation.rb index fb177414..c4e9cd83 100644 --- a/app/app/models/cbv_flow_invitation.rb +++ b/app/app/models/cbv_flow_invitation.rb @@ -1,5 +1,12 @@ class CbvFlowInvitation < ApplicationRecord - EMAIL_REGEX = URI::MailTo::EMAIL_REGEXP + # We're opting not to use URI::MailTo::EMAIL_REGEXP + # https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address + # + # EXCERPT: This requirement is a willful violation of RFC 5322, which defines a syntax for email addresses + # that is simultaneously too strict (before the "@" character), too vague (after the "@" character), + # and too lax (allowing comments, whitespace characters, and quoted strings in manners unfamiliar to most users) + # to be of practical use here. + EMAIL_REGEX = /\A([\w+\-].?)+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z\d\-]+\z/i # Massachusetts: 7 digits MA_AGENCY_ID_REGEX = /\A\d{7}\z/ @@ -13,6 +20,12 @@ class CbvFlowInvitation < ApplicationRecord # New York City: 2 uppercase letters, followed by 5 digits, followed by 1 uppercase letter NYC_CLIENT_ID_REGEX = /\A[A-Z]{2}\d{5}[A-Z]\z/ + # Invitation validity time zone + INVITATION_VALIDITY_TIME_ZONE = "America/New_York" + + # Paystub report range + PAYSTUB_REPORT_RANGE = 90.days + belongs_to :user has_many :cbv_flows @@ -25,18 +38,17 @@ class CbvFlowInvitation < ApplicationRecord validates :first_name, presence: true validates :last_name, presence: true validates :email_address, format: { with: EMAIL_REGEX, message: :invalid_format } - validates :snap_application_date, presence: true # MA specific validations validates :agency_id_number, format: { with: MA_AGENCY_ID_REGEX, message: :invalid_format }, if: :ma_site? validates :beacon_id, format: { with: MA_BEACON_ID_REGEX, message: :invalid_format }, if: :ma_site? validate :ma_snap_application_date_not_more_than_1_year_ago, if: :ma_site? - validate :ma_snap_application_date_not_in_future + validate :ma_snap_application_date_not_in_future, if: :ma_site? # NYC specific validations - validates :case_number, presence: true, format: { with: NYC_CASE_NUMBER_REGEX, message: :invalid_format }, if: :nyc_site? - validates :client_id_number, format: { with: NYC_CLIENT_ID_REGEX, message: :invalid_format }, if: -> { nyc_site? && client_id_number.present? } + validates :case_number, format: { with: NYC_CASE_NUMBER_REGEX, message: :invalid_format }, if: :nyc_site? + validates :client_id_number, format: { with: NYC_CLIENT_ID_REGEX, message: :invalid_format }, if: :nyc_site? validate :nyc_snap_application_date_not_more_than_30_days_ago, if: :nyc_site? validate :nyc_snap_application_date_not_in_future, if: :nyc_site? @@ -54,9 +66,6 @@ class CbvFlowInvitation < ApplicationRecord auth_token: :string ) - INVITATION_VALIDITY_TIME_ZONE = "America/New_York" - PAYSTUB_REPORT_RANGE = 90.days - scope :unstarted, -> { left_outer_joins(:cbv_flows).where(cbv_flows: { id: nil }) } # Invitations are valid until 11:59pm Eastern Time on the (e.g.) 14th day @@ -105,7 +114,15 @@ def parse_snap_application_date new_date_format = Date.strptime(raw_snap_application_date.to_s, "%m/%d/%Y") self.snap_application_date = new_date_format rescue Date::Error => e - errors.add(:snap_application_date, :invalid_date) + case site_id + when "ma" + error = :ma_invalid_date + when "nyc" + error = :nyc_invalid_date + else + error = :invalid_date + end + errors.add(:snap_application_date, error) end end end diff --git a/app/app/services/data_retention_service.rb b/app/app/services/data_retention_service.rb index 829bb122..eb95a99b 100644 --- a/app/app/services/data_retention_service.rb +++ b/app/app/services/data_retention_service.rb @@ -27,8 +27,9 @@ def redact_incomplete_cbv_flows .includes(:cbv_flow_invitation) .find_each do |cbv_flow| invitation_redact_at = cbv_flow.cbv_flow_invitation.expires_at + REDACT_UNUSED_INVITATIONS_AFTER + next unless Time.now.after?(invitation_redact_at) - cbv_flow.redact! if Time.now.after?(invitation_redact_at) + cbv_flow.redact! cbv_flow.cbv_flow_invitation.redact! if cbv_flow.cbv_flow_invitation.present? end end diff --git a/app/app/services/pdf_service.rb b/app/app/services/pdf_service.rb index ba6a450c..21b83800 100644 --- a/app/app/services/pdf_service.rb +++ b/app/app/services/pdf_service.rb @@ -1,7 +1,6 @@ require "pdf-reader" class PdfService - include ApplicationHelper # Represents the result of PDF generation class PdfGenerationResult attr_reader :content, :html, :page_count, :file_size @@ -14,8 +13,8 @@ def initialize(content, html, page_count, file_size) end end - def generate(template:, variables: {}) - html_content = ApplicationController.renderer.render_to_string( + def generate(renderer:, template:, variables: {}) + html_content = renderer.render_to_string( template: template, formats: [ :pdf ], layout: "layouts/pdf", diff --git a/app/app/services/session_invalidation_service.rb b/app/app/services/session_invalidation_service.rb index 2866981d..5a92cc3b 100644 --- a/app/app/services/session_invalidation_service.rb +++ b/app/app/services/session_invalidation_service.rb @@ -33,6 +33,8 @@ def initialize(user, session_id) end def valid? + return false unless @user.present? + (@user.invalidated_session_ids || {}).exclude?(@session_id) end diff --git a/app/app/services/spanish_translation_service.rb b/app/app/services/spanish_translation_service.rb new file mode 100644 index 00000000..a2e6fda9 --- /dev/null +++ b/app/app/services/spanish_translation_service.rb @@ -0,0 +1,91 @@ +require "csv" +require "yaml" + +class SpanishTranslationService + attr_reader :rows, :empty_row_count, :skipped_rows + TARGET_LOCALE = "es" + + def initialize + @rows = [] + @empty_row_count = 0 + @skipped_rows = [] + end + + def generate(csv_filename, output_yaml_path) + csv_path = Rails.root.join(csv_filename) + + # Set default options + translations = { TARGET_LOCALE => {} } + + Rails.logger.info "Attempting to read CSV file: #{csv_path}" + csv_content = File.read(csv_path) + + # Remove the first line if it contains the file label + csv_content = csv_content.lines[1..-1].join if csv_content.lines.first.strip.start_with?("SNAP Income Pilot Translations") + + CSV.parse(csv_content, headers: true, header_converters: :symbol).each_with_index do |row, index| + # skip the header row + next if index.zero? + + if skip_row?(row) + @skipped_rows << row + next + end + + process_row(row, translations[TARGET_LOCALE], TARGET_LOCALE) + end + + log_results + write_yaml(translations, output_yaml_path) + + Rails.logger.info "#{TARGET_LOCALE} translations have been generated and saved to #{output_yaml_path}" + translations + end + + private + + def process_row(row, translations, target_locale) + translation_key = row[:translation_key].to_s.strip.delete_prefix("en.") + translation_value = (row[target_locale.to_sym] || row[:spanish]).to_s.strip + + if translation_value.empty? + @empty_row_count += 1 + return + end + + translation_value = translation_value.split("\n").map(&:strip).join("\n") if translation_value.include?("\n") + + set_nested_hash_value(translations, translation_key.split("."), translation_value) + @rows << row + Rails.logger.info "Processing: Key: '#{translation_key}', Translation: '#{translation_value}'" + end + + def skip_row?(row) + return true if row[:translation_key].to_s.strip.empty? + return true if row[:added_to_confluence]&.strip == "No need for translation" + + false + end + + def log_results + total = @rows.count + @empty_row_count + @skipped_rows.count + puts "Total rows processed: #{total}" + puts "Valid translations found: #{@rows.count}" + puts "Empty rows skipped: #{@empty_row_count}" + puts "Rows skipped by conditions: #{@skipped_rows.count}" + end + + def set_nested_hash_value(hash, keys, value) + key = keys.shift + if keys.empty? + hash[key] = value + else + hash[key] ||= {} + set_nested_hash_value(hash[key], keys, value) + end + end + + def write_yaml(translations, output_yaml_path) + File.open(output_yaml_path, "w") { |file| file.write(translations.to_yaml) } + end +end diff --git a/app/app/views/cbv/payment_details/show.html.erb b/app/app/views/cbv/payment_details/show.html.erb index bd42d737..56aa6124 100644 --- a/app/app/views/cbv/payment_details/show.html.erb +++ b/app/app/views/cbv/payment_details/show.html.erb @@ -7,30 +7,42 @@

    <%= t(".subheader", start_date: @payments_beginning_at, end_date: @payments_ending_at, agency_acronym: current_site.agency_short_name) %>

    -

    <%= t(".total_gross_income", amount: format_money(gross_pay)) %>

    -
    -

    <%= t(".total_gross_description") %>

    -
    -<%= render(TableComponent.new) do |component| %> - <%= component.with_header do %> +<% if @payments.any? %> +

    <%= t(".total_gross_income", amount: format_money(gross_pay)) %>

    +
    +

    <%= t(".total_gross_description") %>

    +
    +<% else %> +

    + <%= t(".none_found") %> +

    +
    +

    + <%= t(".none_found_description") %> +

    +
    +<% end %> + +<%= render(TableComponent.new) do |table| %> + <%= table.with_header do %>

    <%= t("cbv.payment_details.show.employment_information_table_header") %>

    <% end %> - <%= component.with_data_point(:employment_start_date, employment_start_date) %> - <%= component.with_data_point(:employment_end_date, employment_end_date) %> - <%= component.with_data_point(:employment_status, employment_status) %> + <%= table.with_data_point(:employment_start_date, employment_start_date) %> + <%= table.with_data_point(:employment_end_date, employment_end_date) %> + <%= table.with_data_point(:employment_status, employment_status) %> <% if has_income_data? %> - <%= component.with_data_point(:pay_frequency, pay_frequency) %> - <%= component.with_data_point(:hourly_rate, compensation_amount, compensation_unit) %> + <%= table.with_data_point(:pay_frequency, pay_frequency) %> + <%= table.with_data_point(:hourly_rate, compensation_amount, compensation_unit) %> <% end %> <% end %> -<% if @payments.any? %> - <%= render(TableComponent.new) do |table| %> - <%= table.with_header do %> -

    <%= t("cbv.payment_details.show.payments_and_deductions_table_header") %>

    - <% end %> +<%= render(TableComponent.new) do |table| %> + <%= table.with_header do %> +

    <%= t("cbv.payment_details.show.payments_and_deductions_table_header") %>

    + <% end %> + <% if @payments.any? %> <% @payments.each do |payment| %> <%= table.with_row_section do |row| %>

    <%= t("cbv.payment_details.show.pay_date", pay_date: format_date(payment[:pay_date])) %>

    @@ -47,14 +59,12 @@ <%= table.with_data_point(:pay_gross_ytd, payment[:gross_pay_ytd]) %> <% end %> + <% else %> + <%= table.with_row(t(".none_found")) %> <% end %> -<% else %> -

    - <%= t(".none_found") %> -

    <% end %> -
    +

    <%= t(".additional_information_header") %>

    <%= form_with(model: @cbv_flow, url: cbv_flow_payment_details_path, method: :patch) do |form| %> <%= hidden_field_tag "user[account_id]", params[:user][:account_id] %> diff --git a/app/app/views/cbv/summaries/show.html.erb b/app/app/views/cbv/summaries/show.html.erb index 5d7ee132..5b871f15 100644 --- a/app/app/views/cbv/summaries/show.html.erb +++ b/app/app/views/cbv/summaries/show.html.erb @@ -3,56 +3,54 @@ <%= t(".header") %> -<% if @payments.any? %> -
    -

    - <%= t(".description", start_date: @payments_beginning_at, end_date: @payments_ending_at, agency_acronym: current_site.agency_short_name) %> -

    -
    +
    +

    + <%= t(".description", start_date: @payments_beginning_at, end_date: @payments_ending_at, agency_acronym: current_site.agency_short_name) %> +

    +
    -

    <%= t(".total_payments", amount: format_money(total_gross_income)) %>

    -
    -

    <%= t(".total_payments_desc") %>

    -
    +

    <%= t(".total_payments", amount: format_money(total_gross_income)) %>

    +
    +

    <%= t(".total_payments_desc") %>

    +
    - <% payments_grouped_by_employer.each_with_index do |(account_id, summary), index| %> - -

    - <% employer_name = summary[:has_employment_data] ? summary.dig(:employment, "employer_name") : nil %> - <% if employer_name %> - <%= t(".table_caption", number: index + 1, employer_name: employer_name) %> - <% else %> - <%= t(".table_caption_no_name", number: index + 1) %> - <% end %> -

    - - -
    -

    +<% payments_grouped_by_employer.each_with_index do |(account_id, summary), index| %> + +

    + <% employer_name = summary[:has_employment_data] ? summary.dig(:employment, "employer_name") : nil %> + <% if employer_name %> + <%= t(".table_caption", number: index + 1, employer_name: employer_name) %> + <% else %> + <%= t(".table_caption_no_name", number: index + 1) %> + <% end %> +

    + + + + <% else %> + <%= t(".none_found") %> + <% end %> + + + + + + <% summary[:payments].each do |payment| %> + + - - - <% summary[:payments].each do |payment| %> - - - - <% end %> - -
    +

    + <% if summary[:total] > 0 %> <% if employer_name %> <%= t(".total_income_from", employer_name: employer_name, amount: format_money(summary[:total])) %> <% else %> <%= t(".total_income_from_no_employer_name", amount: format_money(summary[:total])) %> <% end %> -

    -
    <%= t(".payment", amount: format_money(payment[:gross_pay_amount]), date: format_date(payment[:pay_date])) %>
    <%= t(".payment", amount: format_money(payment[:gross_pay_amount]), date: format_date(payment[:pay_date])) %>
    -

    <%= t(".additional_comments") %>

    - <%= get_comment_by_account_id(account_id).dig("comment") != "" ? get_comment_by_account_id(account_id).dig("comment") : t("shared.not_applicable") %> - <% end %> -<% else %> -

    - <%= t(".none_found") %> -

    + <% end %> + +
    +

    <%= t(".additional_comments") %>

    + <%= get_comment_by_account_id(account_id).dig("comment") != "" ? get_comment_by_account_id(account_id).dig("comment") : t("shared.not_applicable") %> <% end %> <%= form_with model: @cbv_flow, url: cbv_flow_summary_path, html: { class: "usa-form maxw-full" }, builder: UswdsFormBuilder, method: "patch" do |f| %> diff --git a/app/app/views/cbv/summaries/show.pdf.erb b/app/app/views/cbv/summaries/show.pdf.erb index c2719aa3..5178d002 100644 --- a/app/app/views/cbv/summaries/show.pdf.erb +++ b/app/app/views/cbv/summaries/show.pdf.erb @@ -36,45 +36,21 @@

    Client Information

    <% end %> <% if current_site?(:ma) && !is_caseworker %> - <%= table.with_row( - label: t(".pdf.client.agency_id_number"), - value: @cbv_flow.cbv_flow_invitation.agency_id_number - ) %> + <%= table.with_row(t(".pdf.client.agency_id_number"), @cbv_flow.cbv_flow_invitation.agency_id_number) %> <% end %> <% if is_caseworker %> - <%= table.with_row( - label: t(".pdf.caseworker.first_name"), - value: @cbv_flow.cbv_flow_invitation.first_name - ) %> - <%= table.with_row( - label: t(".pdf.caseworker.middle_name"), - value: @cbv_flow.cbv_flow_invitation.middle_name - ) %> - <%= table.with_row( - label: t(".pdf.caseworker.last_name"), - value: @cbv_flow.cbv_flow_invitation.last_name - ) %> + <%= table.with_row(t(".pdf.caseworker.first_name"), @cbv_flow.cbv_flow_invitation.first_name) %> + <%= table.with_row(t(".pdf.caseworker.middle_name"), @cbv_flow.cbv_flow_invitation.middle_name) %> + <%= table.with_row(t(".pdf.caseworker.last_name"), @cbv_flow.cbv_flow_invitation.last_name) %> <% if current_site?(:nyc) %> - <%= table.with_row( - label: t(".pdf.caseworker.client_id_number"), - value: @cbv_flow.cbv_flow_invitation.client_id_number - ) %> - <%= table.with_row( - label: t(".pdf.caseworker.case_number"), - value: @cbv_flow.cbv_flow_invitation.case_number - ) %> + <%= table.with_row(t(".pdf.caseworker.client_id_number"), @cbv_flow.cbv_flow_invitation.client_id_number) %> + <%= table.with_row(t(".pdf.caseworker.case_number"), @cbv_flow.cbv_flow_invitation.case_number) %> <% end %> <% if current_site?(:ma) %> - <%= table.with_row( - label: t(".pdf.caseworker.client_email_address"), - value: @cbv_flow.cbv_flow_invitation.email_address - ) %> - <%= table.with_row( - label: t(".pdf.caseworker.snap_agency_id"), - value: @cbv_flow.cbv_flow_invitation.agency_id_number - ) %> + <%= table.with_row(t(".pdf.caseworker.client_email_address"), @cbv_flow.cbv_flow_invitation.email_address) %> + <%= table.with_row(t(".pdf.caseworker.snap_agency_id"), @cbv_flow.cbv_flow_invitation.agency_id_number) %> <% end %> <% end %> <% end %> @@ -84,103 +60,95 @@

    Report details

    <% end %> <% if @cbv_flow.confirmation_code.present? %> - <%= table.with_row( - label: t(".pdf.shared.confirmation_code"), - value: @cbv_flow.confirmation_code) - %> + <%= table.with_row(t(".pdf.shared.confirmation_code"), @cbv_flow.confirmation_code) %> <% end %> - <%= table.with_row( - label: site_translation(".application_or_recertification_date"), - value: format_parsed_date(@cbv_flow.cbv_flow_invitation.snap_application_date)) - %> - <%= table.with_row( - label: t(".pdf.client.date_created"), - value: format_parsed_date(@cbv_flow.consented_to_authorized_use_at)) - %> - <%= table.with_row( - label: t(".pdf.client.date_range"), - value: "#{format_parsed_date(@cbv_flow.cbv_flow_invitation.paystubs_query_begins_at)} to #{format_parsed_date(@cbv_flow.cbv_flow_invitation.snap_application_date)}") - %> + <%= table.with_row(site_translation(".application_or_recertification_date"), format_parsed_date(@cbv_flow.cbv_flow_invitation.snap_application_date)) %> + <%= table.with_row(t(".pdf.client.date_created"), format_parsed_date(@cbv_flow.consented_to_authorized_use_at)) %> + <%= table.with_row(t(".pdf.client.date_range"), "#{format_parsed_date(@cbv_flow.cbv_flow_invitation.paystubs_query_begins_at)} to #{format_parsed_date(@cbv_flow.cbv_flow_invitation.snap_application_date)}") %> <% if is_caseworker %> - <%= table.with_row( - label: t(".pdf.caseworker.agreement_consent_timestamp"), - value: @cbv_flow.consented_to_authorized_use_at) - %> + <%= table.with_row(t(".pdf.caseworker.agreement_consent_timestamp"), @cbv_flow.consented_to_authorized_use_at) %> <% if current_site?(:ma) %> - <%= table.with_row( - label: t(".pdf.caseworker.staff_beacon_id_wel_id"), - value: @cbv_flow.cbv_flow_invitation.beacon_id - ) %> + <%= table.with_row(t(".pdf.caseworker.staff_beacon_id_wel_id"), @cbv_flow.cbv_flow_invitation.beacon_id) %> <% end %> <% end %> <% end %>

    <%= t(".pdf.client.employment_payment_details") %>

    -<% if @payments.any? %> - <% payments_grouped_by_employer.each_with_index do |(account_id, summary), index| %> - <% employer_name = summary[:has_employment_data] ? summary.dig(:employment, "employer_name") : nil %> -

    <%= t(".table_caption_no_name", number: index + 1) %>: <%= employer_name %>

    +<% payments_grouped_by_employer.each_with_index do |(account_id, summary), index| %> + <% employer_name = summary[:has_employment_data] ? summary.dig(:employment, "employer_name") : nil %> +

    <%= t(".table_caption_no_name", number: index + 1) %>: <%= employer_name %>

    + <%= render(TableComponent.new) do |table| %> + <%= table.with_header do %> +

    + <% if employer_name %> + <%= employer_name %> — + <% end %> + Employment Information +

    + <% end %> + <% if is_caseworker && summary[:has_identity_data] %> + <%= table.with_data_point(:client_full_name, summary[:identity]["full_name"]) %> + <% end %> + <% if summary[:has_employment_data] %> + <%= table.with_data_point(:employer_phone, summary.dig(:employment, "employer_phone_number", "value")) %> + <%= table.with_data_point(:employer_address, summary.dig(:employment, "employer_address", "raw")) %> + <%= table.with_data_point(:employment_status, summary[:employment]["status"]) %> + <%= table.with_data_point(:employment_start_date, summary[:employment]["start_date"]) %> + <%= table.with_data_point(:employment_end_date, summary[:employment]["termination_date"]) %> + <% end %> + <% if summary[:has_income_data] %> + <%= table.with_data_point(:pay_frequency, summary[:income]["pay_frequency"]&.humanize) %> + <%= table.with_data_point(:hourly_rate, summary[:income]["compensation_amount"], summary[:income]["compensation_unit"]) %> + <% end %> + <% end %> + + <% summary[:payments].each do |payment| %> <%= render(TableComponent.new) do |table| %> <%= table.with_header do %>

    <% if employer_name %> <%= employer_name %> — <% end %> - Employment Information -

    - <% end %> - <% if is_caseworker && summary[:has_identity_data] %> - <%= table.with_data_point(:client_full_name, summary[:identity]["full_name"]) %> - <% end %> - <% if summary[:has_employment_data] %> - <%= table.with_data_point(:employer_phone, summary.dig(:employment, "employer_phone_number", "value")) %> - <%= table.with_data_point(:employer_address, summary.dig(:employment, "employer_address", "raw")) %> - <%= table.with_data_point(:employment_status, summary[:employment]["status"]) %> - <%= table.with_data_point(:employment_start_date, summary[:employment]["start_date"]) %> - <%= table.with_data_point(:employment_end_date, summary[:employment]["termination_date"]) %> + Pay Date: <%= format_date(payment[:pay_date]) %> <% end %> <% if summary[:has_income_data] %> - <%= table.with_data_point(:pay_frequency, summary[:income]["pay_frequency"]&.humanize) %> - <%= table.with_data_point(:hourly_rate, summary[:income]["compensation_amount"], summary[:income]["compensation_unit"]) %> + <%= table.with_data_point(:pay_period_with_frequency, payment[:start], payment[:end], summary[:income]["pay_frequency"]&.humanize, highlight: is_caseworker) %> + <% else %> + <%= table.with_data_point(:pay_period_with_frequency, payment[:start], payment[:end], t("cbv.payment_details.show.frequency_unknown"), highlight: is_caseworker) %> <% end %> - <% end %> - - <% summary[:payments].each do |payment| %> - <%= render(TableComponent.new) do |table| %> - <%= table.with_header do %> -

    - <% if employer_name %> - <%= employer_name %> — - <% end %> - Pay Date: <%= format_date(payment[:pay_date]) %>

    - <% end %> - <% if summary[:has_income_data] %> - <%= table.with_data_point(:pay_period_with_frequency, payment[:start], payment[:end], summary[:income]["pay_frequency"]&.humanize, highlight: is_caseworker) %> - <% else %> - <%= table.with_data_point(:pay_period_with_frequency, payment[:start], payment[:end], t("cbv.payment_details.show.frequency_unknown"), highlight: is_caseworker) %> - <% end %> - <%= table.with_data_point(:pay_gross, payment[:gross_pay_amount], highlight: is_caseworker) %> - <%= table.with_data_point(:number_of_hours_worked, payment[:hours], highlight: is_caseworker) %> - <%= table.with_data_point(:net_pay_amount, payment[:net_pay_amount]) %> + <%= table.with_data_point(:pay_gross, payment[:gross_pay_amount], highlight: is_caseworker) %> + <%= table.with_data_point(:number_of_hours_worked, payment[:hours], highlight: is_caseworker) %> + <%= table.with_data_point(:net_pay_amount, payment[:net_pay_amount]) %> - <% payment[:deductions].filter { |deduction| deduction[:amount] > 0 }.each do |deduction| %> - <%= table.with_data_point(:deduction, deduction[:category], deduction[:amount]) %> - <% end %> + <% payment[:deductions].filter { |deduction| deduction[:amount] > 0 }.each do |deduction| %> + <%= table.with_data_point(:deduction, deduction[:category], deduction[:amount]) %> + <% end %> - <%= table.with_data_point(:pay_gross_ytd, payment[:gross_pay_ytd]) %> + <%= table.with_data_point(:pay_gross_ytd, payment[:gross_pay_ytd]) %> + <% end %> + <% end %> + <% if summary[:payments].empty? %> + <%= render(TableComponent.new) do |table| %> + <%= table.with_header do %> +

    + <% if employer_name %> + <%= employer_name %> — + <% end %> + <%= t(".none_found") %> +

    <% end %> + <%= table.with_row(t(".none_found_confirmed")) %> <% end %> + <% end %> - <% if @cbv_flow.additional_information.dig(account_id, "comment").present? %> -

    <%= t('.additional_information_title') %>

    + <% if @cbv_flow.additional_information.dig(account_id, "comment").present? %> +

    <%= t('.additional_information_title') %>

    -

    <%= @cbv_flow.additional_information.dig(account_id, "comment") %>

    - <% end %> +

    <%= @cbv_flow.additional_information.dig(account_id, "comment") %>

    <% end %> -<% else %> -

    - <%= t('.none_found') %> -

    <% end %> + + + diff --git a/app/config/locales/en.yml b/app/config/locales/en.yml index 0cf94e01..d1008a1c 100644 --- a/app/config/locales/en.yml +++ b/app/config/locales/en.yml @@ -9,10 +9,9 @@ en: blank: Enter a valid agency ID number. invalid_format: Agency ID number must be 7 digits. beacon_id: - blank: can't be blank - invalid_format: Your WelID must be 6 characters. It can only include letters and numbers. + invalid_format: Your WELID must be 6 characters. It can only include letters and numbers. case_number: - invalid_format: Client's case number must be 12 digits. Enter the case number in the ANGIE/sPOS format, i.e. 00012345678A. + invalid_format: Enter the case number in the ANGIE/sPOS format, i.e. 00012345678A. client_id_number: invalid_format: Enter the client's CIN in the correct format, XX00000X. email_address: @@ -23,7 +22,6 @@ en: last_name: blank: Enter the client's last name. snap_application_date: - invalid_date: is not a valid date ma_invalid_date: Enter today's date or the date you contacted the client. This date must be today or in the past year. nyc_invalid_date: SNAP application/recertification date must be today or in the past 30 days. applicant_mailer: @@ -57,7 +55,7 @@ en: ma: invite: agency_id_number: Client's agency ID number - beacon_id: Your WelID + beacon_id: Your WELID email_address: Client's email address first_name: Client's first name last_name: Client's last name @@ -76,7 +74,7 @@ en: first_name: Client's first name last_name: Client's last name middle_name: Client's middle name - snap_application_date: SNAP application date + snap_application_date: SNAP application or recertification date dashboards: show: create_invitation: Create a new invitation @@ -124,7 +122,7 @@ en: create: notice_no_answer: You must select an answer to continue. show: - answer_no_bullet_1: You don't have another job + answer_no_bullet_1: You don't have another job (current or recent) answer_no_bullet_2: You have a job that pays you via PayPal, Venmo, Cash App, etc answer_no_bullet_3: You have a job that pays you in cash answer_no_bullet_4: You have a job that pays you with a paper check and you cannot view your paycheck online @@ -266,7 +264,8 @@ en: header: Your payment information from %{employer_name} header_no_employer_name: Your payment information from your employer hourly_rate: Compensation amount - none_found: No payments found. + none_found: We didn't find any payments from this employer in the past 90 days. + none_found_description: This typically happens when you haven't received income from this job in the past 90 days. If you believe this is an error, please add a comment in the additional comments box. Otherwise, continue to the next page. number_of_hours_worked: Number of hours worked pay_date: 'Pay Date: %{pay_date}' pay_frequency: Pay period frequency @@ -306,7 +305,8 @@ en: consent_to_authorize_use_title: Legal Agreement description: The report below has your income from the past 90 days from, from %{start_date} to %{end_date}. Please review it before you send it to %{agency_acronym}. header: Review and submit your income report - none_found: No payments found. Please refresh the page after a few minutes. + none_found: We didn't find any payments from this employer in the past 90 days. + none_found_confirmed: We've confirmed that there are no payments from this employer in the past 90 days. This happens when the client hasn't received income from this job during that time. payment: Payment of %{amount} before taxes on %{date} pdf: agency_header_name: @@ -327,7 +327,7 @@ en: middle_name: Client's middle name pay_period: Pay period (%{pay_frequency}) snap_agency_id: SNAP Agency ID - staff_beacon_id_wel_id: Staff BEACON ID (WelID) + staff_beacon_id_wel_id: Staff BEACON ID (WELID) client: address: Employer address agency_id_number: Client's Agency ID diff --git a/app/config/locales/es.yml b/app/config/locales/es.yml index 933eef7c..cdd56b57 100644 --- a/app/config/locales/es.yml +++ b/app/config/locales/es.yml @@ -1,10 +1,290 @@ --- es: + applicant_mailer: + invitation_email: + body_1: + ma: "%{agency_acronym} quiere que usted verifique sus ingresos como parte de su solicitud o recertificación del Programa de Asistencia Nutricional Suplementaria (SNAP, por sus siglas en inglés). El SNAP Income Pilot (Piloto de ingresos) es una nueva herramienta diseñada para ayudarle a compartir información de sus ingresos directamente con %{agency_acronym} iniciando sesión en su proveedor de nóminas." + body_2_html: + default: Este proceso es solo para usted. Por favor, no comparta esta invitación con nadie más. Tiene hasta el %{deadline}, para realizar su verificación. De lo contrario, puede solicitar una nueva invitación. + ma: Este proceso es solo para usted. Por favor, no comparta esta invitación con nadie más. Tiene hasta el %{deadline}, para realizar su verificación. + body_3: + default: Esta es una herramienta opcional. Si decide que no desea usarla, puede proveer los documentos de sus ingresos a través de la aplicación %{app_name}, fax, correo postal o en persona. + ma: Esta es una herramienta opcional. Si decide no usarla, puede proveer el comprobante de sus ingresos brutos y horas usando %{app_name}, por fax, por correo postal o en persona. + button: Verifique sus ingresos + button_caption: 'Para verificar sus ingresos con el SNAP Income Pilot, haga clic en el siguiente botón:' + footer: Este es un mensaje generado automáticamente desde su agencia de SNAP. Por favor no conteste a este correo electrónico. + greeting: "¡Hola!" + header: + ma: El Departamento de Asistencia Transitoria (DTA, por sus siglas en inglés) le ha enviado una invitación para verificar sus ingresos + nyc: La Administración de Recursos Humanos (HRA, por sus siglas en inglés) le ha enviado una invitación para verificar sus ingresos + sandbox: La Agencia de pruebas CBV le ha enviado una invitación para verificar sus ingresos + subject: + default: Verifique sus ingresos para su solicitud o renovación de SNAP + ma: Verifique sus ingresos para renovar sus beneficios de SNAP + caseworker: + cbv_flow_invitations: + create: + invite_failed: 'Error al enviar la invitació a %{email_address}: %{error_message}' + invite_success: La invitación ha sido enviada con éxito a %{email_address}. + incorrect_site_id: No se ha podido enviar la invitación porque falta la configuración del sitio. + cbv: + add_jobs: + create: + notice_no_answer: Debe seleccionar una respuesta para continuar. + show: + answer_no_bullet_1: Usted no tiene otro trabajo (actual o reciente) + answer_no_bullet_2: Usted tiene un trabajo que le paga por PayPal, Venmo, Cash App, etc. + answer_no_bullet_3: Usted tiene un trabajo que le paga en efectivo + answer_no_bullet_4: Usted tiene un trabajo que le paga con un cheque impreso y no puede ver su cheque de pago en línea + answer_no_bullet_5: Usted tiene un trabajo que emite un 1099 + answer_no_header: 'Responda que NO si:' + answer_yes_bullet_1: Su trabajo tiene un proveedor de nómina en línea + answer_yes_bullet_2: Su trabajo le permite ver sus talones de pago en línea + answer_yes_bullet_3: Su trabajo se basa en aplicaciones (Uber, DoorDash, Lyft, Instacart, etc.) + answer_yes_header_html: 'Responda que SÍ si cualquiera de las siguientes afirmaciones son ciertas sobre su trabajo actual o reciente:' + continue: Continuar + criteria_disclaimer: 'Nota: Si ha tenido otros trabajos en los últimos %{pay_income_days} días que no cumplen estos criterios, es posible que tenga que presentar información de ese ingreso por separado.' + header: "¿Tiene otro trabajo que declarar?" + learn_more_link_html: + ma: Obtenga más información en el sitio web de DTA. + nyc: Obtenga más información en el sitio web de HRA. + sandbox: Obtenga más información en el sitio web de CBV Test Agency. + no_radio: No, no tengo otro trabajo que cumpla con los criterios + subheader: Por favor añada los otros trabajos que haya tenido en los últimos %{pay_income_days} días, incluso si ya no está en ese trabajo. + yes_radio: Sí, tengo otro trabajo que cumpla con los criterios + agreements: + create: + error: Debe marcar la casilla de «acuerdo» para proceder. + show: + checkbox: + default: Marque esta casilla para indicar que está de acuerdo en permitirnos acceder a su información de pago y compartirla con %{agency_full_name}. + nyc: Marque esta casilla para indicar que está de acuerdo en permitirnos acceder a su información de pago y compartirla con %{agency_full_name}. No usaremos la información para ningún otro fin ni la divulgaremos a terceros. + continue: Continuar + header: Verifiquemos sus ingresos + step1: Busque su más reciente empleador o proveedor de nómina en línea. + step1_description: Un proveedor de nómina es un sistema que usan algunos empleadores o empresas para gestionar la nómina, procesar el pago y distribuir los cheques de pago y los depósitos directos. Algunos ejemplos de proveedores de pago populares son ADP, Paychex, Gusto, etc. + step2: Ingrese a su cuenta de empleador o proveedor de nómina. + step2_description: Use las credenciales de acceso que tiene para visualizar su talón de pago en línea. Si trabaja para una aplicación, tal como Uber, debería ser el mismo inicio de sesión que al ingresar a la aplicación Uber. No almacenaremos ni compartiremos su información de acceso. + step3: Revise su información de pago. + step3_description: La información de pago incluye la fecha de pago, el monto de pago y las horas trabajadas. Repita los pasos del 1 al 3 si tiene otros empleadores que agregar. + step4: Envíe su información de pago. + step4_description: Nosotros la enviaremos automáticamente a %{agency_acronym}. + steps_intro: 'Para verificar sus ingresos, tendrá que completar estos sencillos cuatro pasos:' + employer_searches: + show: + can_not_find_employer: No logro encontrar mi empresa ni mi proveedor de nómina + employer_not_listed: "¿Su empleador no está en la lista?" + exit_button_text: Salga y vaya a %{agency_short_name} + fetching_payroll: Estamos buscando la información de pago de su empleador. + fetching_payroll_description: Esto puede tomar algunos minutos. Por favor, no cierre esta ventana. + header: Busque su más reciente empleador o proveedor de nómina + no_results_steps1: Verifique si su empleador usa otro nombre empresarial o busque a su proveedor de nómina. + no_results_steps2: Asegúrese de haber escrito correctamente los nombres, y busque de nuevo. + no_results_steps_title: 'Intente estos pasos primero:' + no_results_title: No pudimos encontrar su empleador ni su proveedor de nómina. + results: Resultados + review_button_text: Revisar mi informe de ingresos + search: Buscar + search_for_employer: Busque a su empleador o a su proveedor de nómina. Puede ser un antiguo empleador o un empleador actual. Compartiremos su información de ingresos con %{agency_acronym}. + select: Seleccione + select_button_aria_label: Abra una ventana de autenticación para que el empleador o proveedor de nómina importe su historial de pago. + to_access: 'Para acceder a su información de pago, busque alguna de las siguientes opciones:' + to_access_li_1_html: El nombre de su empleador + to_access_li_2_html: El proveedor de nómina del que recibe el pago + to_access_li_3_html: La aplicación con la que trabaja, tal como Uber, DoorDash, etc. + to_continue: 'Si aún no ve enumerado a su empleador ni a su proveedor de nómina:' + to_continue_li_1: Tendrá que enviar esa información de ingresos por separado. + to_continue_li_1_html: + ma: Vaya al sitio web del DTA para informarse de otras formas de notificar sus ingresos. + nyc: Vaya al sitio web de la HRA para informarse de otras formas de notificar sus ingresos. + sandbox: Vaya al sitio web del CBV para informarse de otras formas de notificar sus ingresos. + to_continue_li_2: Si tiene otros trabajos que añadir, búsquelos. + to_continue_li_3: Si no tiene otros trabajos que añadir aquí, puede salir de este sitio. + to_continue_li_3_continue: Si no tiene otros trabajos que añadir aquí, continúe a revisar su informe de ingresos. + what_is_html: "¿Qué es un proveedor de nómina? Un proveedor de nómina es un sistema que usan algunos empleadores o empresas para gestionar la nómina, procesar el pago y distribuir los cheques de pago y los depósitos directos. Algunos ejemplos de proveedores de pago populares son ADP, Paychex, Gusto, etc." + you_ll_go: Usted irá a su portal de inicio de sesión e ingresará para ver su historial de pago. + entries: + show: + cant_use_1: No ha recibido ingresos de un trabajo en los últimos 90 días + cant_use_2: Usted tiene un trabajo que paga por PayPal, Venmo, Cash App, etc. + cant_use_3: Usted tiene un trabajo que paga en efectivo + cant_use_4: Usted tiene un trabajo que le paga con un cheque impreso y no puede ver su cheque de pago en línea + cant_use_5: Usted tiene un trabajo que emite un 1099 + cant_use_if: 'No podrá verificar sus ingresos con esta herramienta si:' + do_app_based_work: Realiza un trabajo que se basa en aplicaciones (como Uber, Lyft, DoorDash) + get_started: Comience + has_income_90_days: 'Puede usar esta herramienta si ha recibido ingresos en los últimos 90 días y:' + has_online_payroll_provider: Puede ver sus cheques de pago a través de su empresa o del proveedor de nómina en línea de su empresa. La mayoría de las personas que reciben talones de pago o formularios de impuesto W-2 tienen un proveedor de nómina en línea. Si no está seguro, pregunte a su empleador. + header: + default: "%{agency_acronym} está lanzando una nueva forma de verificar rápidamente sus ingresos" + ma: Proporcione al %{agency_acronym} sus ingresos de inmediato + security_message_html: "Su información está segura. No compartiremos ni almacenaremos su información de acceso. Podrá revisar y aprobar todo lo que se comparta con %{agency_acronym}." + stopped_working: Dejó de trabajar o perdió un trabajo (pero generó ingresos en los últimos 90 días). + subheader: Enviaremos los registros de pago de su(s) empleador(es) a %{agency_acronym}. Esto le ayudará a demostrar sus ingresos y puede ayudar a %{agency_acronym} a tomar una decisión con mayor rapidez. + subheader_1: Quién puede usar esta herramienta + subheader_2: Quién no puede usar esta herramienta + subheader_3: Qué necesita + you_can_get_started: 'Puede iniciar de inmediato con esta información:' + your_employers_name: El nombre de su empleador o del proveedor de nómina del mismo + your_login_credentials: Su información de acceso para ver sus talones de pago en línea + error_invalid_token: El enlace de invitación no es válido. Vuelva a comprobar el enlace e inténtelo de nuevo. Si sigue teniendo problemas, póngase en contacto con su trabajador social. + error_missing_token_html: "Su sesión a finalizado debido a inactividad. Para continuar donde la dejó, haga clic en el enlace que recibió de su agencia del SNAP por correo electrónico. Si encuentra algún problema, póngase en contacto con su agencia del SNAP para pedir ayuda." + error_no_access: No logramos cargar los datos de nómina para esta cuenta. Haga clic en el enlace que recibió de su agencia del SNAP para intentarlo de nuevo. + expired_invitations: + show: + body_1: Usted ya ha completado con éxito su proceso de verificación, o está intentando acceder a esta invitación después de que ha expirado. + body_2: Si aún debe verificar sus ingresos, comuníquese con su agencia y obtenga una nueva invitación. + cta_button_html: + ma: Visite el sitio web del DTA + nyc: Visite el sitio web de la HRA + sandbox: Obtenga más información en la Agencia de pruebas CBV + title: Su invitación para verificar ingresos ha expirado + missing_results: + show: + back_button: Regrese a la búsqueda del empleador + continue_button: Continúe a «revisar mi informe» + continue_to_review: Continúe a revisar la información de ingresos que logró encontrar antes de enviarla a %{agency_acronym}. + dta_options_1_html: Use DTA Connect para cargar y enviar sus documentos de ingresos. + dta_options_2_html: Envíe sus documentos al DTA por fax junto con una carátula. + dta_options_3_html: Envíe sus documentos al DTA por correo postal junto con una carátula. + dta_options_4_html: Entregue sus documentos en una oficina local del DTA. + dta_options_5_html: Trabaje con un aliado de SNAP Outreach para presentar sus documentos. + dta_options_header: 'Puede presentar su información de ingresos usando uno de los siguientes métodos:' + exit_button_html: + ma: Salga y vaya a DTA + nyc: Salga y vaya a HRA + sandbox: Salga y vaya a la Agencia de prueba CBV + header: Cómo informar sus ingresos si su empleador o proveedor de nómina no están listados + more_jobs: Si tiene más trabajos que reportar + no_more_jobs: Si no tiene más trabajos que reportar + not_listed_p1: Si su empleador o proveedor de nómina no están listados en este sitio, tendrá que compartir su información de ingresos por este trabajo directamente con %{agency_acronym}. + not_listed_p2: Visite %{agency_short_name} para obtener más información sobre cómo presentar documentos. + you_can_search: Puede buscar otro empleador o proveedor de nómina. Este sitio apoya a los empleadores con proveedores de nómina en línea o servicios basados en aplicaciones. Algunos ejemplos son Amazon, Walmart, McDonald’s, Uber, DoorDash, Lyft e Instacart. + payment_details: + show: + additional_information_header: Comentarios adicionales (opcional) + additional_information_label: Comparta cualquier comentario o información adicional sobre los detalles de pago anteriores que desea que %{agency_acronym} conozca. Por ejemplo, puede compartir si la información es inexacta o si ya no trabaja en ese empleo. + continue: Continuar + deductions: 'Deducción: %{category}' + employment_end_date: Fecha de finalización del empleo + employment_information_table_header: Información del empleo + employment_start_date: Fecha de inicio del empleo + employment_status: Estatus del empleo + frequency_unknown: Frecuencia desconocida + header: Su información de pago de %{employer_name} + header_no_employer_name: Su información de pago por parte de su empleador + hourly_rate: Monto de compensación + none_found: No se encontraron pagos. + number_of_hours_worked: Número de horas trabajadas + pay_date: 'Fecha de pago: %{pay_date}' + pay_frequency: Frecuencia del período de pago + pay_gross: Pago antes de impuestos (bruto) + pay_gross_ytd: Remuneración bruta desde el inicio del año a la fecha (YTD, por sus siglas en inglés) + pay_net: Pago después de impuestos y deducciones (neto) + pay_period: Período de pago + payment_hours: "%{amount} horas" + payments_and_deductions_table_header: Pagos y deducciones + subheader: Hemos recopilado sus registros de pago de los últimos 90 días, del %{start_date} al %{end_date}. Si falta información o esta es inexacta, añada un comentario para %{agency_acronym}. Esta información se incluirá en su informe de ingresos. + total_gross_description: Estos son sus ingresos brutos totales provenientes de su trabajo, antes del pago de impuestos, beneficios y deducciones que se restaron de su cheque de pago. + total_gross_income: 'Ingresos totales de los últimos 90 días, antes de impuestos: %{amount}' + unknown: Desconocido + successes: + show: + back_to_agency: Vaya al sitio web de %{agency_short_name} + caseworker_received: Hemos enviado su información de pago a %{agency_acronym}. Ellos lo contactarán si se necesita alguna información adicional. + check_status: + default: Para comprobar el estado de su solicitud o recertificación de SNAP puede visitar el sitio web del DTA. + ma: Para comprobar el estado de su recertificación de SNAP puede visitar el sitio web del DTA. + confirmation_code_html: "Código de confirmación : %{confirmation_code}" + download: Descargue una copia del informe + header: Su informe de ingresos ha sido compartido de forma exitosa con %{agency_acronym} + if_it_didnt_work: Si usted no logró encontrar un empleador, o uno de sus empleadores no tiene un proveedor de nómina en línea, por favor, suministre su información de pago directamente a %{agency_acronym}. + summaries: + show: + additional_comments: Comentarios adicionales + additional_information_title: "¿Hay algo más que desea que su trabajador social sepa sobre sus ingresos?" + application_or_recertification_date: + ma: Fecha de la entrevista de recertificación + nyc: Fecha de solicitud o recertificación + sandbox: Fecha de solicitud o recertificación + consent_to_authorize_use_html: + ma: Marque esta casilla para confirmar que, a su leal saber y entender, la información proporcionada por usted es verdadera y completa. Usted se compromete a informar al DTA sobre cualquier ingreso no reflejado en este informe o cualquier discrepancia hallada en la información recopilada con esta herramienta. Usted entiende que suministrar información precisa y completa es su responsabilidad, y que cualquier información falsa u omitida puede tener consecuencias legales. Para obtener más información sobre sus derechos y responsabilidades en relación a la información privada que comparte con el DTA, consulte los Derechos y Responsabilidades que firmó en la solicitud, que se encuentran en Mass.gov.

    Al enviar este informe, usted autoriza el uso de esta verificación de ingresos por parte de personal autorizado del DTA. + nyc: Marque esta casilla para confirmar que, a su leal saber y entender, la información proporcionada por usted es verdadera y completa. Usted accede a informar a la Administración de Recursos Humanos (HRA) de la Ciudad de Nueva York (NYC, por sus siglas en inglés) de cualquier ingreso no reflejado en este informe o cualquier discrepancia encontrada en la información recopilada con esta herramienta. Usted entiende que suministrar información precisa y completa es su responsabilidad, y que cualquier información falsa u omitida puede tener consecuencias legales.

    Al enviar este informe, autoriza su uso para la verificación de los ingresos por parte del personal autorizado de la HRA. + sandbox: Marque esta casilla para confirmar que, a su leal saber y entender, la información proporcionada por usted es verdadera y completa. Usted se compromete a informar a la Agencia de pruebas CBV sobre cualquier ingreso no reflejado en este informe o cualquier discrepancia hallada en la información recopilada con esta herramienta. Usted entiende que suministrar información precisa y completa es su responsabilidad, y que cualquier información falsa u omitida puede tener consecuencias legales.

    Al enviar este informe, autoriza su uso para la verificación de los ingresos por parte del personal autorizado del CBV. + consent_to_authorize_use_title: Acuerdo legal + description: El siguiente informe contiene sus ingresos de los últimos 90 días, del %{start_date} al %{end_date}. Revíselo antes de enviarlo a %{agency_acronym}. + header: Revise y presente su informe de ingresos + none_found: No se encontraron pagos. Actualice la página después de unos minutos. + payment: Pago de %{amount} antes de pago impuestos en %{date} + pdf: + caseworker: + pay_period: Período de pago (%{pay_frequency}) + client: + address: Dirección del empleador + client_report_information: Información sobre el cliente y el informe + date_created: Fecha en que se creó el informe de ingresos + date_range: Intervalo de fechas para el informe de ingresos + description: Hemos recopilado su información de ingresos con su consentimiento y la hemos enviado a su agencia de SNAP. Cualquier ingreso adicional que no haya logrado agregar a este informe debe compartirlo por separado con su agencia de SNAP. + employment_payment_details: Datos de empleo y pago + header: Informe de verificación de ingresos + shared: + confirmation_code: Código de confirmación + phone_number: Teléfono del empleador + send_report: Comparta mi informe con %{agency_acronym} + table_caption: 'Empleador %{number}: %{employer_name}' + table_caption_no_name: 'Empleador %{number}:' + total_income_from: 'Ingresos totales provenientes de %{employer_name}, antes del pago de impuestos: %{amount}' + total_income_from_no_employer_name: 'Ingresos totales antes del pago de impuestos: %{amount}' + total_payments: 'Ingresos totales de los últimos 90 días, antes del pago de impuestos: %{amount}' + total_payments_desc: Este es el ingreso bruto total de su(s) trabajo(s) antes de que se le descuenten impuestos, beneficios y otras deducciones de su cheque. + update: + consent_to_authorize_warning: Debe marcar la casilla de acuerdo legal para proceder. + pages: + home: + description_1: El SNAP Income Pilot es una nueva herramienta diseñada para ayudarle a conectar los detalles de sus ingresos de su empleador o proveedor de nómina directamente con su agencia de SNAP. Actualmente estamos probando esta herramienta para asegurarnos de que funcione de manera eficaz. + description_2: Tenga en cuenta que este piloto está disponible actualmente solo para los participantes de SNAP en la ciudad de Nueva York y Massachusetts. + description_3_html: '

    Para participar, puede solicitar una invitación a su agencia del SNAP:

    ' + header: Bienvenido al SNAP Income Pilot shared: + agency_full_name: + ma: Departamento de Asistencia Transitoria de Massachusetts + sandbox: Agencia de pruebas CBV + app_name: + ma: DTA Connect + nyc: ACCESS HRA + sandbox: CBVApp banner: lock: Candado - locked_padlock: Candado cerrado + locked_padlock: Un candado cerrado + error_unauthorized: La URL a la que estás accediendo está prohibida para el usuario actual. Verifique que está conectado como el usuario correcto e intente acceder de nuevo a la URL. + footer: + feedback: Notifique comentarios o errores header: + aria_label: Menú principal + cbv_flow_title: + ma: Departamento de Asistencia Transitoria + nyc: Administración de Recursos Humanos + sandbox: Agencia de pruebas CBV close: Cerrar - primary: Navegacion primaria - skip_link: Salte al contenido principal + log_out: Cerrar sesión + preheader: + default: Un sitio web en colaboración con la Agencia de pruebas CBV. + ma: Un sitio web en colaboración con el Estado de Massachusetts. + nyc: Un sitio web en colaboración con la Ciudad de Nueva York. + primary: Menú principal + languages: + en: Inglés + es: Español + fr: Francés + zh: Chino + not_applicable: N/C + pilot_name: SNAP Income Pilot + skip_link: Saltar al contenido principal + us_form_with: + boolean_false: 'No' + boolean_true: Sí + date_picker_format: 'Formato: mm/dd/aaaa' + optional: Opcional + users: + omniauth_callbacks: + authentication_successful: Ha iniciado sesión. diff --git a/app/db/schema.rb b/app/db/schema.rb index 3cdc036f..3dd3de55 100644 --- a/app/db/schema.rb +++ b/app/db/schema.rb @@ -51,8 +51,8 @@ t.string "site_id" t.string "confirmation_code" t.datetime "transmitted_at" - t.datetime "consented_to_authorized_use_at" t.datetime "redacted_at" + t.datetime "consented_to_authorized_use_at" t.index ["cbv_flow_invitation_id"], name: "index_cbv_flows_on_cbv_flow_invitation_id" end diff --git a/app/spec/components/pinwheel_data_point_component_spec.rb b/app/spec/components/pinwheel_data_point_component_spec.rb index 071bebd7..35e4f36f 100644 --- a/app/spec/components/pinwheel_data_point_component_spec.rb +++ b/app/spec/components/pinwheel_data_point_component_spec.rb @@ -39,7 +39,7 @@ expect( render_inline(described_class.new(:deduction, "health_insurance", 10000)) ).to have_text( - "Health insurance\n $100.00\n\n\n" + "Health insurance\n $100.00\n\n\n" ) end diff --git a/app/spec/controllers/caseworker/cbv_flow_invitations_controller/nyc_spec.rb b/app/spec/controllers/caseworker/cbv_flow_invitations_controller/nyc_spec.rb index 80ede733..c7f526ff 100644 --- a/app/spec/controllers/caseworker/cbv_flow_invitations_controller/nyc_spec.rb +++ b/app/spec/controllers/caseworker/cbv_flow_invitations_controller/nyc_spec.rb @@ -50,7 +50,7 @@ it "creates a CbvFlowInvitation record without optional fields" do post :create, params: { site_id: nyc_params[:site_id], - cbv_flow_invitation: cbv_flow_invitation_params.except(:middle_name, :client_id_number) + cbv_flow_invitation: cbv_flow_invitation_params.except(:middle_name) } puts response.inspect invitation = CbvFlowInvitation.last diff --git a/app/spec/controllers/cbv/payment_details_controller_spec.rb b/app/spec/controllers/cbv/payment_details_controller_spec.rb index a9fe7e24..54057e49 100644 --- a/app/spec/controllers/cbv/payment_details_controller_spec.rb +++ b/app/spec/controllers/cbv/payment_details_controller_spec.rb @@ -152,7 +152,7 @@ it "renders properly without the paystubs data" do get :show, params: { user: { account_id: account_id } } expect(response).to be_successful - expect(response.body).to include(I18n.t("cbv.payment_details.show.none_found")) + expect(response.body).to include("find any payments from this employer in the past 90 days.") end end diff --git a/app/spec/controllers/cbv/summaries_controller_spec.rb b/app/spec/controllers/cbv/summaries_controller_spec.rb index 7ab60e75..91c7f1a5 100644 --- a/app/spec/controllers/cbv/summaries_controller_spec.rb +++ b/app/spec/controllers/cbv/summaries_controller_spec.rb @@ -247,7 +247,7 @@ context "when transmission method is s3" do let(:user) { create(:user, email: "test@test.com") } let(:s3_service_double) { instance_double(S3Service) } - let(:pinwheel_service_double) { instance_double(PinwheelService) } + # let(:pinwheel_service_double) { instance_double(PinwheelService) } before do sign_in user allow(S3Service).to receive(:new).and_return(s3_service_double) @@ -264,14 +264,11 @@ allow(controller).to receive(:current_site).and_return(mock_site) # Stub pinwheel_for method to return our double - allow_any_instance_of(ApplicationController).to receive(:pinwheel_for).and_return(pinwheel_service_double) - - # Stub all relevant PinwheelService methods - allow(pinwheel_service_double).to receive(:fetch_accounts).and_return({ "data" => [ { "id" => "sample_account_id" } ] }) - allow(pinwheel_service_double).to receive(:fetch_paystubs).and_return({ "data" => [] }) - allow(pinwheel_service_double).to receive(:fetch_employment).and_return({ "data" => {} }) - allow(pinwheel_service_double).to receive(:fetch_identity).and_return({ "data" => {} }) - allow(pinwheel_service_double).to receive(:fetch_income_metadata).and_return({ "data" => {} }) + stub_request_end_user_accounts_response + stub_request_end_user_paystubs_response + stub_request_employment_info_response + stub_request_income_metadata_response + stub_request_identity_response end it "generates, gzips, encrypts, and uploads PDF and CSV files to S3" do @@ -319,8 +316,8 @@ site_id: cbv_flow.site_id, cbv_flow_id: cbv_flow.id, invitation_id: cbv_flow_invitation.id, - account_count: 0, - paystub_count: 0, + account_count: 1, + paystub_count: 1, account_count_with_additional_information: 0, flow_started_seconds_ago: flow_started_seconds_ago }) diff --git a/app/spec/controllers/concerns/cbv/reports_helper_spec.rb b/app/spec/controllers/concerns/cbv/reports_helper_spec.rb index 423d0088..7253442d 100644 --- a/app/spec/controllers/concerns/cbv/reports_helper_spec.rb +++ b/app/spec/controllers/concerns/cbv/reports_helper_spec.rb @@ -33,7 +33,7 @@ describe "aggregate payments" do it "groups by employer" do - expect(helper.summarize_by_employer(parsed_payments, [ employments ], [ incomes ], [ identities ])).to eq({ + expect(helper.summarize_by_employer(parsed_payments, [ employments ], [ incomes ], [ identities ], cbv_flow.pinwheel_accounts)).to eq({ account_id => { payments: [ { diff --git a/app/spec/controllers/webhooks/pinwheel/events_controller_spec.rb b/app/spec/controllers/webhooks/pinwheel/events_controller_spec.rb new file mode 100644 index 00000000..d35a2cb0 --- /dev/null +++ b/app/spec/controllers/webhooks/pinwheel/events_controller_spec.rb @@ -0,0 +1,124 @@ +require "rails_helper" + +RSpec.describe Webhooks::Pinwheel::EventsController do + include PinwheelApiHelper + + let(:valid_params) do + { + "event" => event_name, + "payload" => payload + } + end + let(:request_headers) do + { + "X-Pinwheel-Signature" => "v2=test-signature", + "X-Timestamp" => "test-timestamp" + } + end + let(:cbv_flow) { create(:cbv_flow, site_id: "sandbox") } + let(:account_id) { "00000000-0000-0000-0000-000000000000" } + + before do + request.headers.merge!(request_headers) + allow_any_instance_of(PinwheelService).to receive(:generate_signature_digest) + .with("test-timestamp", anything) + .and_return("v2=test-signature") + end + + describe "#create" do + let(:supported_jobs) { [ "paystubs", "identity", "income", "employment" ] } + + before do + stub_request_platform_response + end + + context "for an 'account.added' event" do + let(:event_name) { "account.added" } + let(:payload) do + { + "platform_id" => "00000000-0000-0000-0000-000000011111", + "end_user_id" => cbv_flow.pinwheel_end_user_id, + "account_id" => account_id, + "platform_name" => "acme" + } + end + + it "creates a PinwheelAccount object" do + expect(NewRelicEventTracker).to receive(:track) + .with("PinwheelAccountCreated", { + cbv_flow_id: cbv_flow.id, + platform_name: "acme" + }) + + expect do + post :create, params: valid_params + end.to change(PinwheelAccount, :count).by(1) + + pinwheel_account = PinwheelAccount.last + expect(pinwheel_account).to have_attributes( + cbv_flow_id: cbv_flow.id, + supported_jobs: include(*supported_jobs), + pinwheel_account_id: account_id + ) + end + + context "when the webhook signature is incorrect" do + before do + request.headers["X-Pinwheel-Signature"] = "wrong-signature" + end + + it "discards the webhook" do + expect do + post :create, params: valid_params + end.not_to change(PinwheelAccount, :count) + + expect(response).to be_unauthorized + end + end + end + + context "for an 'paystubs.fully_synced' event" do + let(:event_name) { "paystubs.fully_synced" } + let(:payload) do + { + "account_id" => account_id, + "end_user_id" => cbv_flow.pinwheel_end_user_id, + "outcome" => "success" + } + end + let(:pinwheel_account) { PinwheelAccount.create!(cbv_flow: cbv_flow, supported_jobs: supported_jobs, pinwheel_account_id: account_id) } + + it "updates the PinwheelAccount object with the current timestamp" do + expect { post :create, params: valid_params } + .to change { pinwheel_account.reload.paystubs_synced_at } + .from(nil) + .to(within(1.second).of(Time.now)) + end + + it "sends a NewRelic event when fully synced" do + pinwheel_account.update( + created_at: 5.minutes.ago, + employment_synced_at: Time.now, + income_synced_at: Time.now, + identity_synced_at: Time.now, + identity_errored_at: Time.now + ) + expect(NewRelicEventTracker).to receive(:track) + .with("PinwheelAccountSyncFinished", { + cbv_flow_id: cbv_flow.id, + identity_success: false, + identity_supported: true, + income_success: true, + income_supported: true, + employment_success: true, + employment_supported: true, + paystubs_success: true, + paystubs_supported: true, + sync_duration_seconds: within(1.second).of(5.minutes) + }) + + post :create, params: valid_params + end + end + end +end diff --git a/app/spec/models/cbv_flow_invitation_spec.rb b/app/spec/models/cbv_flow_invitation_spec.rb index 965f040f..c35ace05 100644 --- a/app/spec/models/cbv_flow_invitation_spec.rb +++ b/app/spec/models/cbv_flow_invitation_spec.rb @@ -2,11 +2,38 @@ RSpec.describe CbvFlowInvitation, type: :model do let(:valid_attributes) do - attributes_for(:cbv_flow_invitation, :nyc) + attributes_for(:cbv_flow_invitation, :nyc).merge(user: create(:user, site_id: "nyc")) end + let(:invalid_email_no_tld) { "johndoe@gmail" } + let(:valid_email) { "johndoe@gmail.com" } describe "validations" do context "for all invitations" do + context "validates email addresses" do + context "when email address is valid" do + valid_email_addresses = %w[johndoe@gmail.com johndoe@example.com.au johndoe@example.com,johndoe@example.com.au] + valid_email_addresses.each do |email| + it "#{email} is valid" do + invitation = CbvFlowInvitation.new(valid_attributes.merge(email_address: email)) + expect(invitation).to be_valid + end + end + end + + context "when email address is invalid" do + invalid_email_addresses = %w[johndoe@gmail johndoe@gmail..com johndoe@gmail.com..com johndoe@gmail\ .\ com] + invalid_email_addresses.each do |email| + it "determines #{email} is invalid" do + invitation = CbvFlowInvitation.new(valid_attributes.merge(email_address: email)) + expect(invitation).not_to be_valid + expect(invitation.errors[:email_address]).to include( + I18n.t('activerecord.errors.models.cbv_flow_invitation.attributes.email_address.invalid_format') + ) + end + end + end + end + it "requires email_address" do invitation = CbvFlowInvitation.new(valid_attributes.merge(email_address: nil)) expect(invitation).not_to be_valid @@ -27,8 +54,7 @@ invitation = CbvFlowInvitation.new(valid_attributes.merge(snap_application_date: nil)) expect(invitation).not_to be_valid expect(invitation.errors[:snap_application_date]).to include( - I18n.t('activerecord.errors.models.cbv_flow_invitation.attributes.snap_application_date.invalid_date'), - "can't be blank" + I18n.t('activerecord.errors.models.cbv_flow_invitation.attributes.snap_application_date.nyc_invalid_date'), ) end @@ -36,7 +62,7 @@ invitation = CbvFlowInvitation.new(valid_attributes.merge(snap_application_date: Date.tomorrow)) expect(invitation).not_to be_valid expect(invitation.errors[:snap_application_date]).to include( - I18n.t('activerecord.errors.models.cbv_flow_invitation.attributes.snap_application_date.ma_invalid_date') + I18n.t('activerecord.errors.models.cbv_flow_invitation.attributes.snap_application_date.nyc_invalid_date') ) end @@ -50,7 +76,7 @@ invitation = CbvFlowInvitation.new(valid_attributes.merge(snap_application_date: "invalid")) expect(invitation).not_to be_valid expect(invitation.errors[:snap_application_date]).to include( - I18n.t('activerecord.errors.models.cbv_flow_invitation.attributes.snap_application_date.invalid_date') + I18n.t('activerecord.errors.models.cbv_flow_invitation.attributes.snap_application_date.nyc_invalid_date') ) end @@ -123,6 +149,22 @@ I18n.t('activerecord.errors.models.cbv_flow_invitation.attributes.client_id_number.invalid_format') ) end + + it "requires valid snap_application_date" do + invitation = CbvFlowInvitation.new(nyc_attributes.merge(snap_application_date: "invalid")) + expect(invitation).not_to be_valid + expect(invitation.errors[:snap_application_date]).to include( + I18n.t('activerecord.errors.models.cbv_flow_invitation.attributes.snap_application_date.nyc_invalid_date') + ) + end + + it "requires client_id_number" do + invitation = CbvFlowInvitation.new(nyc_attributes.merge(client_id_number: nil)) + expect(invitation).not_to be_valid + expect(invitation.errors[:client_id_number]).to include( + I18n.t('activerecord.errors.models.cbv_flow_invitation.attributes.client_id_number.invalid_format') + ) + end end end diff --git a/app/spec/services/data_retention_service_spec.rb b/app/spec/services/data_retention_service_spec.rb index f469b7eb..79831ad1 100644 --- a/app/spec/services/data_retention_service_spec.rb +++ b/app/spec/services/data_retention_service_spec.rb @@ -58,6 +58,11 @@ expect { service.redact_incomplete_cbv_flows } .not_to change { cbv_flow.reload.attributes } end + + it "does not redact the CbvFlowInvitation" do + expect { service.redact_incomplete_cbv_flows } + .not_to change { cbv_flow_invitation.reload.attributes } + end end context "after the deletion threshold" do @@ -91,6 +96,11 @@ cbv_flow.update(confirmation_code: "SANDBOX001") end + it "does not redact the CbvFlow" do + expect { service.redact_invitations } + .not_to change { cbv_flow.reload.attributes } + end + it "does not redact the invitation" do expect { service.redact_invitations } .not_to change { cbv_flow_invitation.reload.attributes } @@ -130,6 +140,11 @@ expect { service.redact_complete_cbv_flows } .not_to change { cbv_flow.reload.attributes } end + + it "does not redact the CbvFlowInvitation" do + expect { service.redact_complete_cbv_flows } + .not_to change { cbv_flow_invitation.reload.attributes } + end end context "after the deletion threshold" do diff --git a/app/spec/services/pdf_service_spec.rb b/app/spec/services/pdf_service_spec.rb index be0343b5..eee23bed 100644 --- a/app/spec/services/pdf_service_spec.rb +++ b/app/spec/services/pdf_service_spec.rb @@ -21,7 +21,7 @@ let(:employments) { stub_employments(account_id) } let(:incomes) { stub_incomes(account_id) } let(:identities) { stub_identities(account_id) } - let(:payments_grouped_by_employer) { summarize_by_employer(payments, employments, incomes, identities) } + let(:payments_grouped_by_employer) { summarize_by_employer(payments, employments, incomes, identities, cbv_flow.pinwheel_accounts) } let(:variables) do { is_caseworker: true, @@ -44,6 +44,7 @@ it 'generates a PDF file' do pdf_service = PdfService.new @pdf_results = pdf_service.generate( + renderer: ApplicationController.renderer, template: 'cbv/summaries/show', variables: variables ) diff --git a/app/spec/services/session_invalidation_service_spec.rb b/app/spec/services/session_invalidation_service_spec.rb index 92f2b78e..0285bfcc 100644 --- a/app/spec/services/session_invalidation_service_spec.rb +++ b/app/spec/services/session_invalidation_service_spec.rb @@ -12,6 +12,14 @@ end end + context "for a nil User (if they try to log out twice)" do + let(:user) { nil } + + it "is false" do + expect(service.valid?).to eq(false) + end + end + context "for a User with invalidated sessions" do let(:user) { create(:user, invalidated_session_ids: invalidated_session_ids) } let(:invalidated_session_ids) { { "BBBBB" => Time.now } } @@ -65,5 +73,13 @@ end end end + + context "when the user has already logged out" do + let(:user) { nil } + + it "does nothing" do + expect { service.invalidate! }.not_to raise_error + end + end end end diff --git a/app/spec/services/spanish_translation_service_spec.rb b/app/spec/services/spanish_translation_service_spec.rb new file mode 100644 index 00000000..092e651c --- /dev/null +++ b/app/spec/services/spanish_translation_service_spec.rb @@ -0,0 +1,34 @@ +require 'rails_helper' +require 'yaml' + +RSpec.describe SpanishTranslationService do + let(:csv_path) { Rails.root.join('spec', 'support', 'fixtures', 'I18n', 'snap_income_pilot_translations.csv') } + let(:output_path) { Rails.root.join('tmp', 'test.yml') } + + after(:each) do + File.delete(output_path) if File.exist?(output_path) + end + + describe '#generate' do + let(:service) { SpanishTranslationService.new } + + context 'with Spanish translations' do + it 'generates a YAML file with Spanish translations and skips rows based on condition' do + result = service.generate( + csv_path.to_s, + output_path.to_s + ) + + expect(File.exist?(output_path)).to be true + yaml_content = YAML.load_file(output_path) + + # yaml and generated results should match + expect(yaml_content).to eq(result) + expect(yaml_content).to have_key('es') + expect(yaml_content).not_to have_key('en') + expect(yaml_content['es']).not_to be_empty + expect(yaml_content['es'].keys).to include('applicant_mailer', 'caseworker', 'cbv', 'pages', 'shared', 'us_form_with', 'users') + end + end + end +end diff --git a/app/spec/support/fixtures/I18n/snap_income_pilot_translations.csv b/app/spec/support/fixtures/I18n/snap_income_pilot_translations.csv new file mode 100644 index 00000000..77d06ed7 --- /dev/null +++ b/app/spec/support/fixtures/I18n/snap_income_pilot_translations.csv @@ -0,0 +1,444 @@ +SNAP Income Pilot Translations 09132024(09092024) (1) +Translation Key,English,English (removed code),Spanish - from DTA,Spanish,Client or Staff-facing?,Added to Confluence?,Page/location,Error or info banner?,,,,,,,,,,,,,,,,,, +en.applicant_mailer.invitation_email.body_1.default,%{agency_acronym} wants you to verify your income as part of your SNAP application or recertification. The SNAP Income Pilot is a new tool designed to help you share your income data directly with %{agency_acronym} by logging into your payroll provider.,[agency] wants you to verify your income as part of your SNAP application or recertification. The SNAP Income Pilot is a new tool designed to help you share your income data directly with [agency] by logging into your payroll provider.,"[la agencia] quiere que usted verifique sus ingresos como parte de su solicitud o recertificación del Programa de Asistencia Nutricional Suplementaria (SNAP, por sus siglas en inglés). El Income Pilot (Piloto de ingresos) del SNAP es una nueva herramienta diseñada para ayudarlo a compartir los datos sobre sus ingresos directamente con [la agencia] iniciando sesión en su proveedor de nóminas.","%{agency_acronym} quiere que usted verifique sus ingresos como parte de su solicitud o recertificación del Programa de Asistencia Nutricional Suplementaria (SNAP, por sus siglas en inglés). El SNAP Income Pilot (Piloto de ingresos) es una nueva herramienta diseñada para ayudarle a compartir información de sus ingresos directamente con %{agency_acronym} iniciando sesión en su proveedor de nóminas.",Client,Yes,Email invite,,,,,,,,,,,,,,,,,,, +en.applicant_mailer.invitation_email.body_1.ma,%{agency_acronym} wants you to verify your income as part of your SNAP recertification. The SNAP Income Pilot is a new tool designed to help you share your income data directly with %{agency_acronym} by logging into your payroll provider.,[agency] wants you to verify your income as part of your SNAP recertification. The SNAP Income Pilot is a new tool designed to help you share your income data directly with [agency] by logging into your payroll provider.,"[la agencia] quiere que usted verifique sus ingresos como parte de su solicitud o recertificación del Programa de Asistencia Nutricional Suplementaria (SNAP, por sus siglas en inglés). El SNAP Income Pilot (Piloto de ingresos) es una nueva herramienta diseñada para ayudarlo a compartir los datos sobre sus ingresos directamente con [la agencia] iniciando sesión en su proveedor de nóminas.","%{agency_acronym} quiere que usted verifique sus ingresos como parte de su solicitud o recertificación del Programa de Asistencia Nutricional Suplementaria (SNAP, por sus siglas en inglés). El SNAP Income Pilot (Piloto de ingresos) es una nueva herramienta diseñada para ayudarle a compartir información de sus ingresos directamente con %{agency_acronym} iniciando sesión en su proveedor de nóminas.",Client,Yes,Email invite,,,,,,,,,,,,,,,,,,, +en.applicant_mailer.invitation_email.body_2_html.default,"This process is unique to you. Please don't share this invitation with anyone else. You have until %{deadline}, to complete your verification. Otherwise, you can request a new invitation.","This process is unique to you. Please don't share this invitation with anyone else. You have until [date], to complete your verification. Otherwise, you can request a new invitation.","Este proceso es solo para usted. Por favor, no comparta esta invitación con nadie más. Tiene hasta el [fecha], para realizar su verificación. De lo contrario, puede solicitar una nueva invitación.","Este proceso es solo para usted. Por favor, no comparta esta invitación con nadie más. Tiene hasta el %{deadline}, para realizar su verificación. De lo contrario, puede solicitar una nueva invitación.",Client,Yes,Email invite,,,,,,,,,,,,,,,,,,, +en.applicant_mailer.invitation_email.body_2_html.ma,"This process is unique to you. Please don't share this invitation with anyone else. You have until %{deadline}, to complete your verification.","This process is unique to you. Please don't share this invitation with anyone else. You have until [date], to complete your verification.","Este proceso es solo para usted. Por favor, no comparta esta invitación con nadie más. Tiene hasta el [fecha], para realizar su verificación.","Este proceso es solo para usted. Por favor, no comparta esta invitación con nadie más. Tiene hasta el %{deadline}, para realizar su verificación.",Client,Yes,Email invite,,,,,,,,,,,,,,,,,,, +en.applicant_mailer.invitation_email.body_3.default,"This is an optional tool. If you decide that you don't want to use it, you can provide income documents via the %{app_name} app, fax, mail, or in-person.","This is an optional tool. If you decide that you don't want to use it, you can provide income documents via the [agency] app, fax, mail, or in-person.","Esta es una herramienta opcional. Si decide que no desea usarla, puede suministrar los documentos de sus ingresos a través de la aplicación, fax, correo postal [de la agencia] o de forma presencial.","Esta es una herramienta opcional. Si decide que no desea usarla, puede proveer los documentos de sus ingresos a través de la aplicación %{app_name}, fax, correo postal o en persona. ",Client,Yes,Email invite,,,,,,,,,,,,,,,,,,, +en.applicant_mailer.invitation_email.body_3.ma,"This is an optional tool. If you decide that you don't want to use it, you can provide proof of your gross income and hours using %{app_name}, by fax, by mail, or in-person.","This is an optional tool. If you decide that you don't want to use it, you can provide proof of your gross income and hours using [agency app name], by fax, by mail, or in-person.","Esta es una herramienta opcional. Si decide que no quiere usarla, puede proporcionar el comprobante de sus ingresos brutos y horas usando [nombre de la aplicación de la agencia], por fax, por correo postal o en persona.","Esta es una herramienta opcional. Si decide no usarla, puede proveer el comprobante de sus ingresos brutos y horas usando %{app_name}, por fax, por correo postal o en persona.",Client,Yes,Email invite,,,,,,,,,,,,,,,,,,, +en.applicant_mailer.invitation_email.button,Verify your income,,,Verifique sus ingresos,Client,Yes,Email invite,,,,,,,,,,,,,,,,,,, +en.applicant_mailer.invitation_email.button_caption,"To verify your income with the SNAP Income Pilot, click the button below:",,"Para verificar sus ingresos con el SNAP Income Pilot, haga clic en el siguiente botón.","Para verificar sus ingresos con el SNAP Income Pilot, haga clic en el siguiente botón:",Client,Yes,Email invite,,,,,,,,,,,,,,,,,,, +en.applicant_mailer.invitation_email.footer,This is an automatically generated message from your SNAP agency. Please don’t reply to this email.,,Este es un mensaje generado automáticamente desde su agencia del SNAP. No conteste a este correo electrónico.,Este es un mensaje generado automáticamente desde su agencia de SNAP. Por favor no conteste a este correo electrónico.,Client,Yes,Email invite,,,,,,,,,,,,,,,,,,, +en.applicant_mailer.invitation_email.greeting,"Hello,",,¡Hola!,¡Hola!,Client,Yes,Email invite,,,,,,,,,,,,,,,,,,, +en.applicant_mailer.invitation_email.header.ma,DTA has sent you an invitation to verify your income,,"El Departamento de Asistencia Transitoria (DTA, por sus siglas en inglés) le ha enviado una invitación para verificar sus ingresos","El Departamento de Asistencia Transitoria (DTA, por sus siglas en inglés) le ha enviado una invitación para verificar sus ingresos",Client,Yes,Email invite,,,,,,,,,,,,,,,,,,, +en.applicant_mailer.invitation_email.header.nyc,HRA has sent you an invitation to verify your income,,"La Administración de Recursos Humanos (HRA, por sus siglas en inglés) le ha enviado una invitación para verificar sus ingresos","La Administración de Recursos Humanos (HRA, por sus siglas en inglés) le ha enviado una invitación para verificar sus ingresos",Client,Yes,Email invite,,,,,,,,,,,,,,,,,,, +en.applicant_mailer.invitation_email.header.sandbox,CBV Test Agency has sent you an invitation to verify your income,,La Agencia de pruebas CBV le ha enviado una invitación para verificar sus ingresos,La Agencia de pruebas CBV le ha enviado una invitación para verificar sus ingresos,Client,No,Email invite,,,,,,,,,,,,,,,,,,, +en.applicant_mailer.invitation_email.subject.default,Verify your income for your SNAP application or renewal,,Verifique sus ingresos para su solicitud o renovación del SNAP,Verifique sus ingresos para su solicitud o renovación de SNAP,Client,Yes,Email invite,,,,,,,,,,,,,,,,,,, +en.applicant_mailer.invitation_email.subject.ma,Verify your income to renew your SNAP benefits,,Verifique sus ingresos para renovar sus beneficios del SNAP,Verifique sus ingresos para renovar sus beneficios de SNAP,Client,Yes,Email invite,,,,,,,,,,,,,,,,,,, +en.caseworker.cbv_flow_invitations.create.invite_failed,Error sending invitation to %{email_address}: %{error_message}.,Error sending invitation to [email address]: [error message - translated elsewhere],Error al enviar invitación a [dirección de correo electrónico]: [mensaje de error - traducido a otro lugar],Error al enviar la invitació a %{email_address}: %{error_message},Staff,Need to add to error scenarios,Staff dashboard,Yes,,,,,,,,,,,,,,,,,, +en.caseworker.cbv_flow_invitations.create.invite_success,Successfully delivered invitation to %{email_address}.,Successfully delivered invitation to [email address].,Invitación entregada con éxito a [dirección de correo electrónico].,La invitación ha sido enviada con éxito a %{email_address}.,Staff,Need to add to error scenarios,Staff dashboard,Yes,,,,,,,,,,,,,,,,,, +en.caseworker.cbv_flow_invitations.incorrect_site_id,Unable to send invitation due to missing site configuration.,,No se ha podido enviar la invitación porque falta la configuración del sitio.,No se ha podido enviar la invitación porque falta la configuración del sitio.,Staff,Need to add to error scenarios,Staff dashboard,Yes,,,,,,,,,,,,,,,,,, +en.caseworker.cbv_flow_invitations.ma.invite.agency_id_number,Client's agency ID number,,Número de identificación de la agencia del cliente,Número de identificación de la agencia del cliente,Staff,No need for translation,Staff invite ,,,,,,,,,,,,,,,,,,, +en.caseworker.cbv_flow_invitations.ma.invite.beacon_id,Your WELID,,Su WELID,Su WELID,Staff,No need for translation,Staff invite ,,,,,,,,,,,,,,,,,,, +en.caseworker.cbv_flow_invitations.ma.invite.email_address,Client's email address,,Dirección de correo electrónico del cliente,Dirección de correo electrónico del cliente,Staff,No need for translation,Staff invite ,,,,,,,,,,,,,,,,,,, +en.caseworker.cbv_flow_invitations.ma.invite.first_name,Client's first name,,Nombre del cliente,Nombre del cliente,Staff,No need for translation,Staff invite ,,,,,,,,,,,,,,,,,,, +en.caseworker.cbv_flow_invitations.ma.invite.last_name,Client's last name,,Apellido del cliente,Apellido del cliente,Staff,No need for translation,Staff invite ,,,,,,,,,,,,,,,,,,, +en.caseworker.cbv_flow_invitations.ma.invite.middle_name,Client's middle name,,Segundo nombre del cliente,Segundo nombre del cliente,Staff,No need for translation,Staff invite ,,,,,,,,,,,,,,,,,,, +en.caseworker.cbv_flow_invitations.ma.invite.snap_application_date,SNAP application date,,Fecha de solicitud del SNAP,Fecha de solicitud de SNAP,Staff,No need for translation,Staff invite ,,,,,,,,,,,,,,,,,,, +en.caseworker.cbv_flow_invitations.new.description_html,"

    Provide some details about the client so we can send them a link to verify their pay information. We'll request the past %{pay_income_days} days of income, based on the client's application date.

    If multiple members of the household earn income, send an invite link to each household member.

    ","Provide some details about the client so we can send them a link to verify their pay information. We'll request the past [#] days of income, based on the client's application date. If multiple members of the household earn income, send an invite link to each household member.","Suministre algunos datos sobre el cliente para que podamos enviarle un enlace para verificar su información de pago. Solicitaremos los últimos [#] días de ingresos, en base a la fecha de solicitud del cliente. Si varios miembros del grupo familiar devengan ingresos, envíe un enlace de invitación a cada miembro de la familia.","

    Provea algunos datos sobre el cliente para que podamos enviarle un enlace para verificar su información de pago. Solicitaremos los últimos %{pay_income_days} días de ingresos, en base a la fecha de solicitud del cliente.

    Si varios miembros de la familia reciben ingresos, envíe un enlace de invitación a cada miembro de la familia.

    ",Staff,No need for translation,Staff invite ,,,,,,,,,,,,,,,,,,, +en.caseworker.cbv_flow_invitations.new.form.submit,Send Invitation,,Envíe una invitación,Envíe una invitación,Staff,No need for translation,Staff invite ,,,,,,,,,,,,,,,,,,, +en.caseworker.cbv_flow_invitations.new.header,Send an invite link,,Envíe un enlace de invitación,Envíe un enlace de invitación,Staff,No need for translation,Staff invite ,,,,,,,,,,,,,,,,,,, +en.caseworker.cbv_flow_invitations.nyc.invite.case_number,Case number,,Número de caso,Número de caso,Staff,No need for translation,Staff invite ,,,,,,,,,,,,,,,,,,, +en.caseworker.cbv_flow_invitations.nyc.invite.client_id_number,CIN,,CIN,CIN,Staff,No need for translation,Staff invite ,,,,,,,,,,,,,,,,,,, +en.caseworker.cbv_flow_invitations.nyc.invite.email_address,Client's email address,,Dirección de correo electrónico del cliente,Dirección de correo electrónico del cliente,Staff,No need for translation,Staff invite ,,,,,,,,,,,,,,,,,,, +en.caseworker.cbv_flow_invitations.nyc.invite.first_name,Client's first name,,Nombre del cliente,Nombre del cliente,Staff,No need for translation,Staff invite ,,,,,,,,,,,,,,,,,,, +en.caseworker.cbv_flow_invitations.nyc.invite.last_name,Client's last name,,Apellido del cliente,Apellido del cliente,Staff,No need for translation,Staff invite ,,,,,,,,,,,,,,,,,,, +en.caseworker.cbv_flow_invitations.nyc.invite.middle_name,Client's middle name,,Segundo nombre del cliente,Segundo nombre del cliente,Staff,No need for translation,Staff invite ,,,,,,,,,,,,,,,,,,, +en.caseworker.cbv_flow_invitations.nyc.invite.snap_application_date,SNAP application date,,Fecha de solicitud del SNAP,Fecha de solicitud del SNAP,Staff,No need for translation,Staff invite ,,,,,,,,,,,,,,,,,,, +en.caseworker.dashboards.show.create_invitation,Create a new invitation,,Cree una nueva invitación,Cree una nueva invitación,Staff,No need for translation,Staff dashboard,,,,,,,,,,,,,,,,,,, +en.caseworker.dashboards.show.expires_within.one,%{count} day,[#] day,[#] día,%{count} día,Staff,No need for translation,Staff invite ,,,,,,,,,,,,,,,,,,, +en.caseworker.dashboards.show.expires_within.other,%{count} days,[#] days,[#] días,%{count} días,Staff,No need for translation,Staff invite ,,,,,,,,,,,,,,,,,,, +en.caseworker.dashboards.show.header,Invite clients to the SNAP Income Pilot,,Invite a clientes al SNAP Income Pilot,Invite a clientes al SNAP Income Pilot,Staff,No need for translation,Staff dashboard,,,,,,,,,,,,,,,,,,, +en.caseworker.dashboards.show.helpful_reminders,Helpful reminders,,Recordatorios útiles,Recordatorios útiles,Staff,No need for translation,Staff dashboard,,,,,,,,,,,,,,,,,,, +en.caseworker.dashboards.show.invite_clients,"You can invite clients to use this income verification tool by clicking the ""Create a new invitation"" button below.",,Puede invitar a los clientes a usar esta herramienta de verificación haciendo clic en el botón «Create a new invitation» (Crear una nueva invitación) a continuación.,Puede invitar a los clientes a usar esta herramienta de verificación haciendo clic en el botón «Create a new invitation» (Crear una nueva invitación) a continuación.,Staff,No need for translation,Staff dashboard,,,,,,,,,,,,,,,,,,, +en.caseworker.dashboards.show.reminder_1,"If multiple household members earn income, send an invite link to each member individually.",,"Si varios miembros del grupo familiar devengan ingresos, envíe un enlace de invitación a cada miembro individualmente.","Si varios miembros de la familia reciben ingresos, envíe un enlace de invitación a cada miembro individualmente.",Staff,No need for translation,Staff dashboard,,,,,,,,,,,,,,,,,,, +en.caseworker.dashboards.show.reminder_2,"If an invitation link has expired, you can generate a new one on this page. Links expire if not accessed within %{expires_days} or if they have already been used to share the PDF report.","If an invitation link has expired, you can generate a new one on this page. Links expire if not accessed within [#] or if they have already been used to share the PDF report.","Si un enlace de invitación ha expirado, puede generar uno nuevo en esta página. Los enlaces caducan si no se accede a ellos en un plazo de [#] o si ya han sido usados para compartir el informe PDF.","Si un enlace de invitación ha expirado, puede generar uno nuevo en esta página. Los enlaces caducan si no se accede a ellos en un plazo de %{expires_days} o si ya han sido usados para compartir el informe PDF.",Staff,No need for translation,Staff dashboard,,,,,,,,,,,,,,,,,,, +en.caseworker.dashboards.show.reminder_3,"For security reasons, you'll be logged out after 30 minutes of inactivity.",,"Por motivos de seguridad, se cerrará la sesión después de 30 minutos de inactividad.","Por motivos de seguridad, se cerrará la sesión después de 30 minutos de inactividad.",Staff,No need for translation,Staff dashboard,,,,,,,,,,,,,,,,,,, +en.caseworker.dashboards.show.reminder_4,"If you encounter any issues with the tool, please use the Report feedback or bugs link.",,"Si tiene algún problema con la herramienta, use el enlace de Notificación de comentarios o errores.","Si tiene algún problema con la herramienta, use el enlace de Reporte comentarios o errores.",Staff,No need for translation,Staff dashboard,,,,,,,,,,,,,,,,,,, +en.caseworker.entries.index.continue_to_login.ma,Continue to DTA log in page,,Avance a la página de inicio de sesión del DTA.,Continúe a la página de inicio de sesión del DTA,Staff,No need for translation,Staff entry,,,,,,,,,,,,,,,,,,, +en.caseworker.entries.index.continue_to_login.nyc,Log in with your LAN ID,,"Inicie sesión con su identificación de la red de área local (LAN ID, por sus siglas en inglés)","Inicie sesión con su identificación de la red de área local (LAN ID, por sus siglas en inglés)",Staff,No need for translation,Staff entry,,,,,,,,,,,,,,,,,,, +en.caseworker.entries.index.continue_to_login.sandbox,Continue to CBV Test Agency log in page,,Avance a la página de inicio de sesión de la Agencia de pruebas CBV,Avance a la página de inicio de sesión de la Agencia de pruebas CBV,Staff,No need for translation, ,,,,,,,,,,,,,,,,,,, +en.caseworker.entries.index.description.ma,"This site allows staff at participating agencies to send clients a link to verify their income, so they can easily send pay information to the agency.",,"Este sitio le permite al personal de las agencias participantes enviar un enlace a los clientes para verificar sus ingresos, para que puedan enviar información de pago a la agencia fácilmente.","Este sitio le permite al personal de las agencias participantes enviar un enlace a los clientes para verificar sus ingresos, para que puedan enviar información de pago a la agencia fácilmente.",Staff,No need for translation,Staff entry,,,,,,,,,,,,,,,,,,, +en.caseworker.entries.index.description.nyc,"This site allows staff at participating agencies to send clients a link to verify their income, so they can easily send pay information to the agency.",,"Este sitio le permite al personal de las agencias participantes enviar un enlace a los clientes para verificar sus ingresos, para que puedan enviar información de pago a la agencia fácilmente.","Este sitio le permite al personal de las agencias participantes enviar un enlace a los clientes para verificar sus ingresos, para que puedan enviar información de pago a la agencia fácilmente.",Staff,No need for translation,Staff entry,,,,,,,,,,,,,,,,,,, +en.caseworker.entries.index.description.sandbox,"This site allows staff at participating agencies to send clients a link to verify their income, so they can easily send pay information to the agency.",,"Este sitio le permite al personal de las agencias participantes enviar un enlace a los clientes para verificar sus ingresos, para que puedan enviar información de pago a la agencia fácilmente.","Este sitio le permite al personal de las agencias participantes enviar un enlace a los clientes para verificar sus ingresos, para que puedan enviar información de pago a la agencia fácilmente.",Staff,No need for translation,Staff entry,,,,,,,,,,,,,,,,,,, +en.caseworker.entries.index.header.ma,DTA is piloting a new way to quickly verify clients' income,,El DTA está poniendo a prueba una nueva forma de verificar rápidamente los ingresos de los clientes,El DTA está lanzando una nueva forma de verificar rápidamente los ingresos de sus clientes,Staff,No need for translation,Staff entry,,,,,,,,,,,,,,,,,,, +en.caseworker.entries.index.header.nyc,HRA is piloting a new way to quickly verify clients' income,,"La Administración de Recursos Humanos (HRA, por sus siglas en inglés) está poniendo a prueba una nueva forma de verificar rápidamente los ingresos de los clientes","La Administración de Recursos Humanos (HRA, por sus siglas en inglés) está lanzazndo una nueva forma de verificar rápidamente los ingresos de sus clientes",Staff,No need for translation,Staff entry,,,,,,,,,,,,,,,,,,, +en.caseworker.entries.index.header.sandbox,CBV Test Agency is piloting a new way to quickly verify clients' income,,La Agencia de pruebas CBV está poniendo a prueba una nueva forma de verificar rápidamente los ingresos de los clientes,La Agencia de pruebas CBV está lanzando una nueva forma de verificar rápidamente los ingresos de los clientes,Staff,No need for translation,Staff entry,,,,,,,,,,,,,,,,,,, +en.caseworker.entries.index.how_it_works,How it works,,Cómo funciona,Cómo funciona,Staff,No need for translation,Staff entry,,,,,,,,,,,,,,,,,,, +en.caseworker.entries.index.step_1_description,"For security, you will be automatically logged out after 30 minutes of inactivity.",,"Por seguridad, se cerrará la sesión después de 30 minutos de inactividad.","Por seguridad, se cerrará la sesión después de 30 minutos de inactividad.",Staff,No need for translation,Staff entry,,,,,,,,,,,,,,,,,,, +en.caseworker.entries.index.step_1_title.default,Log in using your existing agency account.,,Inicie sesión usando su cuenta existente de la agencia.,Inicie sesión usando su cuenta existente de la agencia.,Staff,No need for translation, ,,,,,,,,,,,,,,,,,,, +en.caseworker.entries.index.step_1_title.nyc,Log in using your existing agency account (LAN ID).,,Inicie sesión usando su cuenta existente de la agencia (LAN ID),Inicie sesión usando su cuenta existente de la agencia (LAN ID).,Staff,No need for translation,Staff entry,,,,,,,,,,,,,,,,,,, +en.caseworker.entries.index.step_2_description,"Invitations are for individual clients. If you need to verify income for multiple people in a household, you will need to create a new invitation for each person.",,"Las invitaciones son para clientes particulares. Si necesita verificar los ingresos de varias personas de un grupo familiar, tendrá que crear una invitación nueva para cada persona.","Las invitaciones son para clientes individuales. Si necesita verificar los ingresos de varios miembros en una familia, tendrá que crear una invitación nueva para cada persona.",Staff,No need for translation,Staff entry,,,,,,,,,,,,,,,,,,, +en.caseworker.entries.index.step_2_title,"Click the ""Create a new invitation"" button.",,Haga clic en el botón «Create a new invitation» (Cree una nueva invitación).,Haga clic en el botón «Create a new invitation» (Cree una nueva invitación).,Staff,No need for translation,Staff dashboard,,,,,,,,,,,,,,,,,,, +en.caseworker.entries.index.step_3_description,"When you submit their name, ID number, email address, and application date, we'll email them an invitation link to verify their income.",,"Cuando usted envíe el nombre, número de identificación, dirección de correo electrónico y fecha de solicitud (del cliente), le enviaremos (al cliente) un enlace de invitación para que verifiquen sus ingresos.","Cuando usted envíe el nombre, número de identificación, dirección de correo electrónico y fecha de solicitud (del cliente), enviaremos al cliente un enlace de invitación para que verifique sus ingresos.",Staff,No need for translation,Staff entry,,,,,,,,,,,,,,,,,,, +en.caseworker.entries.index.step_3_title,Provide information about the client. We'll send them an invitation.,,Suministre información del cliente. Le enviaremos una invitación.,Suministre información del cliente. Le enviaremos una invitación.,Staff,No need for translation,Staff entry,,,,,,,,,,,,,,,,,,, +en.caseworker.entries.index.step_4_description,The information will be uploaded as a PDF to the case.,,La información se cargará al caso como un PDF.,La información se cargará al caso como un PDF.,Staff,No need for translation,Staff entry,,,,,,,,,,,,,,,,,,, +en.caseworker.entries.index.step_4_title,"Once the client verifies their income, you'll receive their income information.",,"Una vez que el cliente verifique sus ingresos, usted recibirá esa información de ingresos.","Una vez que el cliente verifique sus ingresos, usted recibirá esa información de ingresos.",Staff,No need for translation,Staff entry,,,,,,,,,,,,,,,,,,, +en.caseworker_mailer.summary_email.greeting,"Hello,",,¡Hola!,¡Hola!,Staff,No need for translation,Staff incoming report email,,,,,,,,,,,,,,,,,,, +en.caseworker_mailer.summary_email.subject,Income Verification Report %{case_number} has been received,Income Verification Report [#] has been received,Se ha recibido el Informe [#] de verificación de ingresos,Se ha recibido el Informe %{case_number} de verificación de ingresos,Staff,No need for translation,Staff incoming report email,,,,,,,,,,,,,,,,,,, +en.cbv.add_jobs.create.notice_no_answer,You must select an answer to continue.,,Debe seleccionar una respuesta para continuar.,Debe seleccionar una respuesta para continuar.,Client,,Add job,Yes,,,,,,,,,,,,,,,,,, +en.cbv.add_jobs.show.answer_no_bullet_1,You don't have another current or recent job job,You don’t have another current or recent job,Usted no tiene otro trabajo actual o reciente ,Usted no tiene otro trabajo actual o reciente ,Client,Yes,Add job,,,,,,,,,,,,,,,,,,, +en.cbv.add_jobs.show.answer_no_bullet_2,"You have a job that pays you via PayPal, Venmo, Cash App, etc",,"Usted tiene un trabajo que le paga por PayPal, Venmo, Cash App, etc.","Usted tiene un trabajo que le paga por PayPal, Venmo, Cash App, etc.",Client,Yes,Add job,,,,,,,,,,,,,,,,,,, +en.cbv.add_jobs.show.answer_no_bullet_3,You have a job that pays you in cash,,Usted tiene un trabajo que le paga en efectivo,Usted tiene un trabajo que le paga en efectivo,Client,Yes,Add job,,,,,,,,,,,,,,,,,,, +en.cbv.add_jobs.show.answer_no_bullet_4,You have a job that pays you with a paper check and you cannot view your paycheck online,,Usted tiene un trabajo que le paga con un cheque impreso y no puede ver su cheque de pago en línea,Usted tiene un trabajo que le paga con un cheque impreso y no puede ver su cheque de pago en línea,Client,Yes,Add job,,,,,,,,,,,,,,,,,,, +en.cbv.add_jobs.show.answer_no_bullet_5,You have a job that issues a 1099,,Usted tiene un trabajo que emite un 1099,Usted tiene un trabajo que emite un 1099,Client,Yes,Add job,,,,,,,,,,,,,,,,,,, +en.cbv.add_jobs.show.answer_no_header,Answer NO if:,,Responda que NO si:,Responda que NO si:,Client,Yes,Add job,,,,,,,,,,,,,,,,,,, +en.cbv.add_jobs.show.answer_yes_bullet_1,Your job has an online payroll provider,,Su trabajo tiene un proveedor de nómina en línea,Su trabajo tiene un proveedor de nómina en línea,Client,Yes,Add job,,,,,,,,,,,,,,,,,,, +en.cbv.add_jobs.show.answer_yes_bullet_2,Your job lets you view pay stubs online,,Su trabajo le permite ver sus talones de pago en línea,Su trabajo le permite ver sus talones de pago en línea,Client,Yes,Add job,,,,,,,,,,,,,,,,,,, +en.cbv.add_jobs.show.answer_yes_bullet_3,"Your job is app-based (Uber, DoorDash, Lyft, Instacart, etc.)",,"Su trabajo se basa en aplicaciones (Uber, DoorDash, Lyft, Instacart, etc.)","Su trabajo se basa en aplicaciones (Uber, DoorDash, Lyft, Instacart, etc.)",Client,Yes,Add job,,,,,,,,,,,,,,,,,,, +en.cbv.add_jobs.show.answer_yes_header_html,Answer YES if any of these are true about your current or recent job:,Answer YES if any of these are true about your current or recent job:,Responda que SÍ si cualquiera de las siguientes (afirmaciones) son ciertas sobre su trabajo actual o reciente:,Responda que SÍ si cualquiera de las siguientes afirmaciones son ciertas sobre su trabajo actual o reciente:,Client,Yes,Add job,,,,,,,,,,,,,,,,,,, +en.cbv.add_jobs.show.continue,Continue,,Continuar,Continuar,Client,Yes,Add job,,,,,,,,,,,,,,,,,,, +en.cbv.add_jobs.show.criteria_disclaimer,"Note: If you've had other jobs in the past %{pay_income_days} days that don't meet these criteria, you may need to submit that income information separately.","Note: If you've had other jobs in the past [#] days that don't meet these criteria, you may need to submit that income information separately.","Nota: Si ha tenido otros trabajos en los últimos [#] días que no cumplen estos criterios, es posible que tenga que presentar esa información de ese ingreso por separado.","Nota: Si ha tenido otros trabajos en los últimos %{pay_income_days} días que no cumplen estos criterios, es posible que tenga que presentar información de ese ingreso por separado.",Client,Yes,Add job,,,,,,,,,,,,,,,,,,, +en.cbv.add_jobs.show.header,Do you have another job to report?,,¿Tiene otro trabajo que notificar?,¿Tiene otro trabajo que declarar?,Client,Yes,Add job,,,,,,,,,,,,,,,,,,, +en.cbv.add_jobs.show.learn_more_link_html.ma,"Learn more on DTA's website.",Learn more on [agency] website.,Obtenga más información en el sitio web [de la agencia].,"Obtenga más información en el sitio web de DTA.",Client,Yes,Add job,,,,,,,,,,,,,,,,,,, +en.cbv.add_jobs.show.learn_more_link_html.nyc,"Learn more on HRA's website.",,,"Obtenga más información en el sitio web de HRA.",Client,Yes,Add job,,,,,,,,,,,,,,,,,,, +en.cbv.add_jobs.show.learn_more_link_html.sandbox,"Learn more on CBV Test Agency's website.",,,"Obtenga más información en el sitio web de CBV Test Agency.",Client,No,Add job,,,,,,,,,,,,,,,,,,, +en.cbv.add_jobs.show.no_radio,"No, I don’t have another job that meets the criteria",,"No, no tengo otro trabajo que cumpla los criterios","No, no tengo otro trabajo que cumpla con los criterios",Client,Yes,Add job,,,,,,,,,,,,,,,,,,, +en.cbv.add_jobs.show.subheader,"Please add other jobs you’ve had in the past %{pay_income_days} days, even if you're no longer at that job.","Please add other jobs you’ve had in the past [#] days, even if you're no longer at that job.","Añada los otros trabajos que haya tenido en los últimos [#] días, incluso si ya no está en ese trabajo.","Por favor añada los otros trabajos que haya tenido en los últimos %{pay_income_days} días, incluso si ya no está en ese trabajo.",Client,Yes,Add job,,,,,,,,,,,,,,,,,,, +en.cbv.add_jobs.show.yes_radio,"Yes, I have another job that meets the criteria",,"Sí, tengo otro trabajo que cumple los criterios","Sí, tengo otro trabajo que cumpla con los criterios",Client,Yes,Add job,,,,,,,,,,,,,,,,,,, +en.cbv.agreements.create.error,You must check the agreement checkbox to proceed.,,Debe marcar la casilla de «acuerdo» para proceder.,Debe marcar la casilla de «acuerdo» para proceder.,Client,Need to add,Agreement,Yes,,,,,,,,,,,,,,,,,, +en.cbv.agreements.show.checkbox.default,Check this box to agree to let us access your payment information and share it with the %{agency_full_name}.,Check this box to agree to let us access your payment information and share it with the [agency].,Marque esta casilla para indicar que está de acuerdo en permitirnos acceder a su información de pago y compartirla con la [agencia].,Marque esta casilla para indicar que está de acuerdo en permitirnos acceder a su información de pago y compartirla con %{agency_full_name}.,Client,Yes,Agreement,,,,,,,,,,,,,,,,,,, +en.cbv.agreements.show.checkbox.nyc,Check this box to agree to let Nava access your payment information and share it with the %{agency_full_name}. We will not use the information for any other purpose nor redisclose it to any other party.,Check this box to agree to let us access your payment information and share it with the [agency]. We will not use the information for any other purpose nor redisclose it to any other party.,Marque esta casilla para indicar que está de acuerdo en permitirnos acceder a su información de pago y compartirla con la [agencia]. No usaremos la información para ningún otro fin ni la divulgaremos a terceros.,Marque esta casilla para indicar que está de acuerdo en permitirnos acceder a su información de pago y compartirla con %{agency_full_name}. No usaremos la información para ningún otro fin ni la divulgaremos a terceros.,Client,Yes,Agreement,,,,,,,,,,,,,,,,,,, +en.cbv.agreements.show.continue,Continue,,Continuar,Continuar,Client,Yes,Agreement,,,,,,,,,,,,,,,,,,, +en.cbv.agreements.show.header,Let's verify your income,,Verifiquemos su ingreso,Verifiquemos sus ingresos,Client,Yes,Agreement,,,,,,,,,,,,,,,,,,, +en.cbv.agreements.show.step1,Find your most recent employer or online payroll provider.,,Busque su más reciente empleador o proveedor de nómina en línea.,Busque su más reciente empleador o proveedor de nómina en línea.,Client,Yes,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.agreements.show.step1_description,"A payroll provider is a system that some employers or companies use to handle payroll, pay processing, and distribute paychecks and direct deposit. Examples of popular payroll providers are ADP, Paychex, Gusto, etc.",,"Un proveedor de nómina es un sistema que usan algunos empleadores o empresas para gestionar la nómina, procesar el pago y distribuir los cheques de pago y los depósitos directos. Algunos ejemplos de proveedores de pago populares son ADP, Paychex, Gusto, etc.","Un proveedor de nómina es un sistema que usan algunos empleadores o empresas para gestionar la nómina, procesar el pago y distribuir los cheques de pago y los depósitos directos. Algunos ejemplos de proveedores de pago populares son ADP, Paychex, Gusto, etc.",Client,Yes,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.agreements.show.step2,Sign into your employer or payroll provider account.,,Ingrese a su cuenta del empleador o proveedor de nómina.,Ingrese a su cuenta de empleador o proveedor de nómina.,Client,Yes,Agreement,,,,,,,,,,,,,,,,,,, +en.cbv.agreements.show.step2_description,"Use the login credentials you have for viewing your online pay stub. If you work for an app, like Uber, this would be the same login when you sign into the Uber app. We will not share or keep your login information.",,"Use las credenciales de acceso que tiene para visualizar su talón de pago en línea. Si trabaja para una aplicación, tal como Uber, debería ser el mismo inicio de sesión que al ingresar a la aplicación Uber. No almacenaremos ni compartiremos su información de acceso.","Use las credenciales de acceso que tiene para visualizar su talón de pago en línea. Si trabaja para una aplicación, tal como Uber, debería ser el mismo inicio de sesión que al ingresar a la aplicación Uber. No almacenaremos ni compartiremos su información de acceso.",Client,Yes,Agreement,,,,,,,,,,,,,,,,,,, +en.cbv.agreements.show.step3,Review your payment information.,,Revise su información de pago.,Revise su información de pago.,Client,Yes,Agreement,,,,,,,,,,,,,,,,,,, +en.cbv.agreements.show.step3_description,"Payment information includes pay date, pay amount, and hours worked. Repeat steps 1 to 3 if you have other employers to add.",,"La información de pago incluye la fecha de pago, el monto de pago y las horas trabajadas. Repita los pasos del 1 al 3 si tiene otros empleados que agregar.","La información de pago incluye la fecha de pago, el monto de pago y las horas trabajadas. Repita los pasos del 1 al 3 si tiene otros empleadores que agregar.",Client,Yes,Agreement,,,,,,,,,,,,,,,,,,, +en.cbv.agreements.show.step4,Submit your payment information.,,Envíe su información de pago.,Envíe su información de pago.,Client,Yes,Agreement,,,,,,,,,,,,,,,,,,, +en.cbv.agreements.show.step4_description,We’ll automatically send it to %{agency_acronym}.,We’ll automatically send it to [agency].,Nosotros la enviaremos automáticamente a la [agencia].,Nosotros la enviaremos automáticamente a %{agency_acronym}.,Client,Yes,Agreement,,,,,,,,,,,,,,,,,,, +en.cbv.agreements.show.steps_intro,"To verify your income, you'll need to complete these four simple steps:",,"Para verificar su ingreso, tendrá que completar estos sencillos cuatro pasos:","Para verificar sus ingresos, tendrá que completar estos sencillos cuatro pasos:",Client,Yes,Agreement,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.can_not_find_employer,I can’t find my company or payroll provider,,No logro encontrar mi empresa ni mi proveedor de nómina,No logro encontrar mi empresa ni mi proveedor de nómina,Client,Yes,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.employer_not_listed,Employer not listed?,,¿El empleador no está listado?,¿Su empleador no está en la lista?,Client,Yes,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.exit_button_text,Exit and go to %{agency_short_name},Exit and go to [agency].,Salga y vaya a la [agencia].,Salga y vaya a %{agency_short_name},Client,Yes,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.fetching_payroll,We are fetching your employer's payment information.,,Estamos buscando la información de pago de su empleador.,Estamos buscando la información de pago de su empleador.,Client,Yes,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.fetching_payroll_description,This may take a few minutes. Please do not close this window.,,"Esto puede tomar algunos minutos. Por favor, no cierre esta ventana.","Esto puede tomar algunos minutos. Por favor, no cierre esta ventana.",Client,Yes,Synchronizations,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.header,Find your current or most recent employer or payroll provider,,Busque su más reciente empleador o proveedor de nómina,Busque su más reciente empleador o proveedor de nómina,Client,Yes,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.no_results_steps1,Check if your employer uses another business name or search for their payroll provider.,,Verifique si su empleador usa otro nombre empresarial o busque a su proveedor de nómina.,Verifique si su empleador usa otro nombre empresarial o busque a su proveedor de nómina.,Client,Yes,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.no_results_steps2,"Make sure you have spelled names correctly, then search again.",,"Asegúrese de haber escrito correctamente los nombres, luego busque de nuevo.","Asegúrese de haber escrito correctamente los nombres, y busque de nuevo.",Client,Yes,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.no_results_steps_title,Try these steps first:,,Intente estos pasos primero:,Intente estos pasos primero:,Client,Yes,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.no_results_title,We couldn’t find your employer or payroll provider.,,No pudimos encontrar a su empleador ni a su proveedor de nómina.,No pudimos encontrar su empleador ni su proveedor de nómina.,Client,Yes,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.results,Results,,Resultados,Resultados,Client,Yes,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.review_button_text,Review my income report,,Revisar mi informe de ingresos,Revisar mi informe de ingresos,Client,Yes,Summary,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.search,Search,,Búsqueda,Buscar,Client,Yes,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.search_for_employer,Search for your employer or payroll provider. This can be a former employer or a current employer. We will share your income information with %{agency_acronym}.,Search for your employer or payroll provider. This can be a former employer or a current employer. We will share your income information with [agency].,Busque a su empleador o a su proveedor de nómina. Puede ser un antiguo empleador o un empleador actual. Compartiremos su información de ingresos con [agencia].,Busque a su empleador o a su proveedor de nómina. Puede ser un antiguo empleador o un empleador actual. Compartiremos su información de ingresos con %{agency_acronym}.,Client,Yes,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.select,Select,,Seleccione,Seleccione,Client,Yes,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.select_button_aria_label,Open an authentication modal for the employer or payroll provider to import your payment history.,,Abra una modalidad de autenticación para que el empleador o proveedor de nómina importe su historial de pago.,Abra una ventana de autenticación para que el empleador o proveedor de nómina importe su historial de pago.,Client,,,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.to_access,"To access your payment information, search for any of the following:",,"Para acceder a su información de pago, busque alguna de las siguientes opciones:","Para acceder a su información de pago, busque alguna de las siguientes opciones:",Client,Yes,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.to_access_li_1_html,Your employer name,Your employer name,El nombre de su empleador,El nombre de su empleador,Client,Yes,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.to_access_li_2_html,The payroll provider you get paid from,The payroll provider you get paid from,El proveedor de nómina del que recibe el pago,El proveedor de nómina del que recibe el pago,Client,Yes,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.to_access_li_3_html,"The app you work for, like Uber, DoorDash, etc","The app you work for, like Uber, DoorDash, etc","La aplicación con la que trabaja, tal como Uber, DoorDash, etc.","La aplicación con la que trabaja, tal como Uber, DoorDash, etc.",Client,Yes,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.to_continue,If you still don’t see your employer or payroll provider listed:,,Si aún no ve a enumerado a su empleador ni a su proveedor de nómina:,Si aún no ve enumerado a su empleador ni a su proveedor de nómina:,Client,Yes,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.to_continue_li_1,You’ll need to submit that income information separately.,,Tendrá que enviar la información de ingreso por separado.,Tendrá que enviar esa información de ingresos por separado.,Client,Yes,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.to_continue_li_1_html.ma,"Go to DTA's website to learn about other ways to report your income.",Go to DTA's website to learn about other ways to report your income.,Vaya al sitio web para informarse de otras formas de notificar sus ingresos.,"Vaya al sitio web del DTA para informarse de otras formas de notificar sus ingresos.",Client,Yes,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.to_continue_li_1_html.nyc,"Go to HRA's website to learn about other ways to report your income.",Go to HRA's website to learn about other ways to report your income.,Vaya al sitio web de la HRA para informarse de otras formas de notificar sus ingresos.,"Vaya al sitio web de la HRA para informarse de otras formas de notificar sus ingresos.",Client,Yes,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.to_continue_li_1_html.sandbox,"Go to CBV's website to learn about other ways to report your income.",Go to CBV's website to learn about other ways to report your income.,Vaya al sitio web del CBV para informarse de otras formas de notificar sus ingresos.,"Vaya al sitio web del CBV para informarse de otras formas de notificar sus ingresos.",Client,No,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.to_continue_li_2,"If you have other jobs to add, search for them.",,"Si tiene otros trabajos que añadir, búsquelos.","Si tiene otros trabajos que añadir, búsquelos.",Client,Yes,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.to_continue_li_3,"If you have no other jobs to add here, you can exit this site.",,"Si no tiene otros trabajos que añadir aquí, puede salir de este sitio.","Si no tiene otros trabajos que añadir aquí, puede salir de este sitio.",Client,Yes,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.to_continue_li_3_continue,"If you have no other jobs to add here, continue to review your income report.",,"Si no tiene otros trabajos que añadir aquí, pase a revisar su informe de ingresos.","Si no tiene otros trabajos que añadir aquí, continúe a revisar su informe de ingresos.",Client,Yes,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.what_is_html,"What is a payroll provider? A payroll provider is a system that some employers or companies use to handle payroll, pay processing, and distribute paychecks and direct deposit. Examples of popular payroll providers are ADP, Paychex, Gusto, etc.","What is a payroll provider? A payroll provider is a system that some employers or companies use to handle payroll, pay processing, and distribute paychecks and direct deposit. Examples of popular payroll providers are ADP, Paychex, Gusto, etc.","¿Qué es un proveedor de nómina? Un proveedor de nómina es un sistema que usan algunos empleadores o empresas para gestionar la nómina, procesar el pago y distribuir los cheques de pago y los depósitos directos. Algunos ejemplos de proveedores de pago populares son ADP, Paychex, Gusto, etc.","¿Qué es un proveedor de nómina? Un proveedor de nómina es un sistema que usan algunos empleadores o empresas para gestionar la nómina, procesar el pago y distribuir los cheques de pago y los depósitos directos. Algunos ejemplos de proveedores de pago populares son ADP, Paychex, Gusto, etc.",Client,Yes,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.employer_searches.show.you_ll_go,You’ll go to their login portal and sign in to see your payment history.,,Usted irá a su portal de inicio de sesión e ingresará para ver su historial de pago.,Usted irá a su portal de inicio de sesión e ingresará para ver su historial de pago.,Client,Yes,Employer search,,,,,,,,,,,,,,,,,,, +en.cbv.entries.show.cant_use_1,You haven’t earned income from a job in the past 90 days,,No ha devengado ingresos de un trabajo en los últimos 90 días,No ha recibido ingresos de un trabajo en los últimos 90 días,Client,Yes,Entry,,,,,,,,,,,,,,,,,,, +en.cbv.entries.show.cant_use_2,"You have a job that pays via PayPal, Venmo, Cash App, etc.",,"Usted tiene un trabajo que paga por PayPal, Venmo, Cash App, etc.","Usted tiene un trabajo que paga por PayPal, Venmo, Cash App, etc.",Client,Yes,Entry,,,,,,,,,,,,,,,,,,, +en.cbv.entries.show.cant_use_3,You have a job that pays in cash,,Usted tiene un trabajo que paga en efectivo,Usted tiene un trabajo que paga en efectivo,Client,Yes,Entry,,,,,,,,,,,,,,,,,,, +en.cbv.entries.show.cant_use_4,You have a job that pays you with a paper check and you cannot view your paycheck online,,Usted tiene un trabajo que le paga con un cheque impreso y no puede ver su cheque de pago en línea,Usted tiene un trabajo que le paga con un cheque impreso y no puede ver su cheque de pago en línea,Client,Yes,Entry,,,,,,,,,,,,,,,,,,, +en.cbv.entries.show.cant_use_5,You have a job that issues a 1099,,Usted tiene un trabajo que emite un 1099,Usted tiene un trabajo que emite un 1099,Client,Yes,Entry,,,,,,,,,,,,,,,,,,, +en.cbv.entries.show.cant_use_if,You won't be able to verify your income with this tool if:,,No podrá verificar sus ingresos con esta herramienta si:,No podrá verificar sus ingresos con esta herramienta si:,Client,Yes,Entry,,,,,,,,,,,,,,,,,,, +en.cbv.entries.show.do_app_based_work,"Do app-based gig work (like Uber, Lyft, DoorDash)",,"Realiza un trabajo que se basa en aplicaciones (como Uber, Lyft, DoorDash)","Realiza un trabajo que se basa en aplicaciones (como Uber, Lyft, DoorDash)",Client,Yes,Entry,,,,,,,,,,,,,,,,,,, +en.cbv.entries.show.get_started,Get Started,,Comience,Comience,Client,Yes,Entry,,,,,,,,,,,,,,,,,,, +en.cbv.entries.show.has_income_90_days,You can use this tool if you have earned income in the last 90 days and:,,Puede usar esta herramienta si ha devengado ingresos en los últimos 90 días y:,Puede usar esta herramienta si ha recibido ingresos en los últimos 90 días y:,Client,Yes,Entry,,,,,,,,,,,,,,,,,,, +en.cbv.entries.show.has_online_payroll_provider,"Can view your paychecks through your company or company's online payroll provider. Most people who receive pay stubs or W-2 tax forms have an online payroll provider. If you’re unsure, ask your employer.",,"Puede ver sus cheques de pago a través de su empresa o del proveedor de nómina en línea de su empresa. La mayoría de las personas que reciben talones de pago o formularios de impuesto W-2 tienen un proveedor de nómina en línea. Si no está seguro, pregunte a su empleador.","Puede ver sus cheques de pago a través de su empresa o del proveedor de nómina en línea de su empresa. La mayoría de las personas que reciben talones de pago o formularios de impuesto W-2 tienen un proveedor de nómina en línea. Si no está seguro, pregunte a su empleador.",Client,Yes,Entry,,,,,,,,,,,,,,,,,,, +en.cbv.entries.show.header.default,%{agency_acronym} is piloting a new way to quickly verify your income,[agency] is piloting a new way to quickly verify your income,la [agencia] está poniendo a prueba una nueva forma de verificar rápidamente sus ingresos,%{agency_acronym} está lanzando una nueva forma de verificar rápidamente sus ingresos,Client,Yes,Entry,,,,,,,,,,,,,,,,,,, +en.cbv.entries.show.header.ma,Get %{agency_acronym} your income right away,,Obtenga %{agency_acronym} sus ingresos de inmediato,Proporcione al %{agency_acronym} sus ingresos de inmediato,Client,Yes,Entry,,,,,,,,,,,,,,,,,,, +en.cbv.entries.show.security_message_html,Your information is secure. We won't share or keep your log in information. You will be able to preview and approve everything that is shared with %{agency_acronym}.,Your information is secure. We won't share or keep your log in information. You will be able to preview and approve everything that is shared with [agency].,Su información está segura. No compartiremos ni almacenaremos su información de acceso. Podrá visualizar previamente y aprobar todo lo que se comparta con [agencia].,Su información está segura. No compartiremos ni almacenaremos su información de acceso. Podrá revisar y aprobar todo lo que se comparta con %{agency_acronym}.,Client,Yes,Entry,,,,,,,,,,,,,,,,,,, +en.cbv.entries.show.stopped_working,Have stopped working or lost a job (but earned income in the past 90 days).,,Dejó de trabajar o perdió un trabajo (pero devengó ingresos en los últimos 90 días).,Dejó de trabajar o perdió un trabajo (pero generó ingresos en los últimos 90 días).,Client,Yes,Entry,,,,,,,,,,,,,,,,,,, +en.cbv.entries.show.subheader,We’ll send the payment records from your employer(s) to %{agency_acronym}. This will help you prove your income and can help %{agency_acronym} get to a decision faster.,We’ll send the payment records from your employer(s) to [agency]. This will help you prove your income and can help [agency] get to a decision faster.,Enviaremos los registros de pago de su(s) empleador(es) a la [agencia]. Esto lo ayudará a demostrar sus ingresos y puede ayudar a la [agencia] a tomar una decisión con mayor rapidez.,Enviaremos los registros de pago de su(s) empleador(es) a %{agency_acronym}. Esto le ayudará a demostrar sus ingresos y puede ayudar a %{agency_acronym} a tomar una decisión con mayor rapidez.,Client,Yes,Entry,,,,,,,,,,,,,,,,,,, +en.cbv.entries.show.subheader_1,Who can use this tool,,Quién puede usar esta herramienta,Quién puede usar esta herramienta,Client,Yes,Entry,,,,,,,,,,,,,,,,,,, +en.cbv.entries.show.subheader_2,Who can't use this tool,,Quién no puede usar esta herramienta,Quién no puede usar esta herramienta,Client,Yes,Entry,,,,,,,,,,,,,,,,,,, +en.cbv.entries.show.subheader_3,What you need,,Qué necesita,Qué necesita,Client,Yes,Entry,,,,,,,,,,,,,,,,,,, +en.cbv.entries.show.you_can_get_started,You can get started right away with this information:,,Puede iniciar de inmediato con esta información:,Puede iniciar de inmediato con esta información:,Client,Yes,Entry,,,,,,,,,,,,,,,,,,, +en.cbv.entries.show.your_employers_name,Your employer's name or the name of their payroll provider,,El nombre de su empleador o del proveedor de nómina del mismo,El nombre de su empleador o del proveedor de nómina del mismo,Client,Yes,Entry,,,,,,,,,,,,,,,,,,, +en.cbv.entries.show.your_login_credentials,Your login information for viewing your paystubs online,,Su información de acceso para ver sus talones de pago en línea,Su información de acceso para ver sus talones de pago en línea,Client,Yes,Entry,,,,,,,,,,,,,,,,,,, +en.cbv.error_invalid_token,"The invitation link used is not valid. Double check the link and try again. If you continue experiencing issues, contact your caseworker.",,"El enlace de invitación no es válido. Vuelva a comprobar el enlace e inténtalo de nuevo. Si sigue teniendo problemas, póngase en contacto con su trabajador social.","El enlace de invitación no es válido. Vuelva a comprobar el enlace e inténtelo de nuevo. Si sigue teniendo problemas, póngase en contacto con su trabajador social.",Client,Need to add,?,Yes,,,,,,,,,,,,,,,,,, +en.cbv.error_missing_token_html,"Your session has timed out due to inactivity. To continue where you left off, please click the link you received from your SNAP agency in your email. If you encounter any issues, contact your SNAP agency for assistance.","Your session has timed out due to inactivity. To continue where you left off, please click the link you received from your SNAP agency in your email. If you encounter any issues, contact your SNAP agency for assistance.","Su sesión a finalizado debido a la inactividad. Para continuar donde lo dejó, haga clic en el enlace que recibió de su agencia del SNAP por correo electrónico. Si se le presenta algún problema, póngase en contacto con su agencia del SNAP para pedir ayuda.","Su sesión a finalizado debido a inactividad. Para continuar donde la dejó, haga clic en el enlace que recibió de su agencia del SNAP por correo electrónico. Si encuentra algún problema, póngase en contacto con su agencia del SNAP para pedir ayuda.",Client,Yes,Welcome,Yes,,,,,,,,,,,,,,,,,, +en.cbv.error_no_access,We weren't able to load payroll data for this account. Please click the link you received from your SNAP agency to try again.,,No logramos cargar los datos de nómina para esta cuenta. Haga clic en el enlace que recibió de su agencia del SNAP para intentarlo de nuevo.,No logramos cargar los datos de nómina para esta cuenta. Haga clic en el enlace que recibió de su agencia del SNAP para intentarlo de nuevo.,Client,Need to add,?,Yes,,,,,,,,,,,,,,,,,, +en.cbv.expired_invitations.show.body_1,"You've either successfully completed your verification process, or are trying to access this invitation after it has expired.",,"Usted ya ha completado con éxito su proceso de verificación, o está intentando acceder a esta invitación después de que ha expirado.","Usted ya ha completado con éxito su proceso de verificación, o está intentando acceder a esta invitación después de que ha expirado.",Client,Yes,Expired,,,,,,,,,,,,,,,,,,, +en.cbv.expired_invitations.show.body_2,"If you still need to verify your income, please reach out to your agency to get a new invitation.",,"Si aún debe verificar sus ingresos, comuníquese con su agencia y obtenga una nueva invitación.","Si aún debe verificar sus ingresos, comuníquese con su agencia y obtenga una nueva invitación.",Client,Yes,Expired,,,,,,,,,,,,,,,,,,, +en.cbv.expired_invitations.show.cta_button_html.ma,"Visit DTA's website",Visit DTA website,Visite el sitio web del DTA,"Visite el sitio web del DTA",Client,Yes,Expired,,,,,,,,,,,,,,,,,,, +en.cbv.expired_invitations.show.cta_button_html.nyc,"Visit HRA's website",Visit HRA website,Visite el sitio web de la HRA,"Visite el sitio web de la HRA",Client,Yes,Expired,,,,,,,,,,,,,,,,,,, +en.cbv.expired_invitations.show.cta_button_html.sandbox,"Learn more at CBV Test Agency",Learn more at CBV Test Agency,Obtenga más información en la Agencia de pruebas CBV,"Obtenga más información en la Agencia de pruebas CBV",Client,Yes,Expired,,,,,,,,,,,,,,,,,,, +en.cbv.expired_invitations.show.title,Your invitation to verify income has expired,,Su invitación para verificar ingresos ha expirado.,Su invitación para verificar ingresos ha expirado,Client,Yes,Expired,,,,,,,,,,,,,,,,,,, +en.cbv.missing_results.show.back_button,Go back to employer search,,Regrese a la búsqueda del empleador,Regrese a la búsqueda del empleador,Client,,,,,,,,,,,,,,,,,,,,, +en.cbv.missing_results.show.continue_button,Continue to review my report,,Continúe a «revisar mi informe»,Continúe a «revisar mi informe»,Client,Yes,Missing results,,,,,,,,,,,,,,,,,,, +en.cbv.missing_results.show.continue_to_review,Continue to review the income information you were able to find before you submit it to %{agency_acronym}.,Continue to review the income information you were able to find before you submit it to [agency].,Continúe a revisar la información de ingresos que logró encontrar antes de enviarla a la [agencia].,Continúe a revisar la información de ingresos que logró encontrar antes de enviarla a %{agency_acronym}.,Client,Yes,Missing results,,,,,,,,,,,,,,,,,,, +en.cbv.missing_results.show.dta_options_1_html,"Use DTA Connect to upload and submit your income documents.",Use DTA Connect to upload and submit your income documents.,Use DTA Connect para cargar y enviar sus documentos de ingresos.,"Use DTA Connect para cargar y enviar sus documentos de ingresos.",Client,Yes,Missing results,,,,,,,,,,,,,,,,,,, +en.cbv.missing_results.show.dta_options_2_html,"Fax your documents to DTA along with a cover sheet.",Fax your documents to DTA along with a cover sheet.,Envíe sus documentos al DTA por fax junto con una carátula.,"Envíe sus documentos al DTA por fax junto con una carátula.",Client,Yes,Missing results,,,,,,,,,,,,,,,,,,, +en.cbv.missing_results.show.dta_options_3_html,"Mail your documents to DTA along with a cover sheet.",Mail your documents to DTA along with a cover sheet.,Envíe sus documentos al DTA por correo postal junto con una carátula.,"Envíe sus documentos al DTA por correo postal junto con una carátula.",Client,Yes,Missing results,,,,,,,,,,,,,,,,,,, +en.cbv.missing_results.show.dta_options_4_html,"Drop your documents off at a local DTA office.",Drop your documents off at a local DTA office.,Entregue sus documentos en una oficina local del DTA.,"Entregue sus documentos en una oficina local del DTA.",Client,Yes,Missing results,,,,,,,,,,,,,,,,,,, +en.cbv.missing_results.show.dta_options_5_html,"Work with a SNAP Outreach Partner to submit your documents.",Work with a SNAP Outreach Partner to submit your documents.,Trabaje con un aliado de SNAP Outreach para presentar sus documentos.,"Trabaje con un aliado de SNAP Outreach para presentar sus documentos.",Client,Yes,Missing results,,,,,,,,,,,,,,,,,,, +en.cbv.missing_results.show.dta_options_header,You can submit your income information using one of the following methods:,,Puede presentar su información de ingresos usando uno de los siguientes métodos:,Puede presentar su información de ingresos usando uno de los siguientes métodos:,Client,Yes,Missing results,,,,,,,,,,,,,,,,,,, +en.cbv.missing_results.show.exit_button_html.ma,"Exit and go to DTA",Exit and go to DTA,Salga y vaya al DTA,"Salga y vaya a DTA",Client,Yes,Missing results,,,,,,,,,,,,,,,,,,, +en.cbv.missing_results.show.exit_button_html.nyc,"Exit and go to HRA",Exit and go to HRA,Salga y vaya a la HRA,"Salga y vaya a HRA",Client,Yes,Missing results,,,,,,,,,,,,,,,,,,, +en.cbv.missing_results.show.exit_button_html.sandbox,"Exit and go to CBV Test Agency",Exit and go to CBV Test Agency,Salga y vaya a la Agencia de prueba CBV,"Salga y vaya a la Agencia de prueba CBV",Client,No,Missing results,,,,,,,,,,,,,,,,,,, +en.cbv.missing_results.show.header,How to report income if your employer or payroll provider isn’t listed,,Cómo informar sus ingresos si su empleador o proveedor de nómina no están listados,Cómo informar sus ingresos si su empleador o proveedor de nómina no están listados,Client,Yes,Missing results,,,,,,,,,,,,,,,,,,, +en.cbv.missing_results.show.more_jobs,If you have more jobs to report,,Si tiene más trabajos que notificar,Si tiene más trabajos que reportar,Client,Yes,Missing results,,,,,,,,,,,,,,,,,,, +en.cbv.missing_results.show.no_more_jobs,If you don't have more jobs to report,,Si no tiene más trabajos que notificar,Si no tiene más trabajos que reportar,Client,Yes,Missing results,,,,,,,,,,,,,,,,,,, +en.cbv.missing_results.show.not_listed_p1,"If your employer or payroll provider isn’t listed on this site, you’ll need to share your income information for this job directly with %{agency_acronym}.","If your employer or payroll provider isn’t listed on this site, you’ll need to share your income information for this job directly with [agency].","Si su empleador o proveedor de nómina no están listados en este sitio, tendrá que compartir su información de ingresos por este trabajo directamente con [agencia].","Si su empleador o proveedor de nómina no están listados en este sitio, tendrá que compartir su información de ingresos por este trabajo directamente con %{agency_acronym}.",Client,Yes,Missing results,,,,,,,,,,,,,,,,,,, +en.cbv.missing_results.show.not_listed_p2,Visit %{agency_short_name} for more information on how to submit documents.,Visit [agency] for more information on how to submit documents.,Visite [agencia] para obtener más información sobre cómo presentar documentos.,Visite %{agency_short_name} para obtener más información sobre cómo presentar documentos.,Client,Yes,Missing results,,,,,,,,,,,,,,,,,,, +en.cbv.missing_results.show.you_can_search,"You can search for another employer or payroll provider. This site supports employers with online payroll providers or app-based services. Examples include Amazon, Walmart, McDonald’s, Uber, DoorDash, Lyft, and Instacart.",,"Puede buscar a su empleador o a su proveedor de nómina. Este sitio apoya a los empleadores con proveedores de nómina en línea o servicios basados en aplicaciones. Algunos ejemplos son Amazon, Walmart, McDonald’s, Uber, DoorDash, Lyft e Instacart.","Puede buscar otro empleador o proveedor de nómina. Este sitio apoya a los empleadores con proveedores de nómina en línea o servicios basados en aplicaciones. Algunos ejemplos son Amazon, Walmart, McDonald’s, Uber, DoorDash, Lyft e Instacart.",Client,Yes,Missing results,,,,,,,,,,,,,,,,,,, +en.cbv.payment_details.show.additional_information_header,Additional comments (optional),,Comentarios adicionales (opcional),Comentarios adicionales (opcional),Client,Yes,Payment details,,,,,,,,,,,,,,,,,,, +en.cbv.payment_details.show.additional_information_label,"Share any comments or additional information about the payment details above that you’d like %{agency_acronym} to know. For example, you can share if the information is inaccurate or if you’re no longer working at that job.","Share any comments or additional information about the payment details above that you’d like [agency] to know. For example, you can share if the information is inaccurate or if you’re no longer working at that job.","Comparta cualquier comentario o información adicional sobre los detalles de pago anteriores que desea que [agencia] conozca. Por ejemplo, puedo compartir si la información es inexacta o si ya no trabaja en ese empleo.","Comparta cualquier comentario o información adicional sobre los detalles de pago anteriores que desea que %{agency_acronym} conozca. Por ejemplo, puede compartir si la información es inexacta o si ya no trabaja en ese empleo.",Client,Yes,Payment details,,,,,,,,,,,,,,,,,,, +en.cbv.payment_details.show.continue,Continue,,Continuar,Continuar,Client,Yes,Payment details,,,,,,,,,,,,,,,,,,, +en.cbv.payment_details.show.deductions,Deduction: %{category},Deduction: [category],Deducción: [categoría],Deducción: %{category},Client,Yes,Payment details,,,,,,,,,,,,,,,,,,, +,,"[deduction category] +charity +child support +commuter +company perk +dental +disability +fees +fsa +hsa +job expense +lending +life insurance +loan +medical insurance +other +reallocation +retirement +retro pay +savings +stock +tax +tips +union dues +vision +wage garnishment","[categoría de deducción] +caridad +manutención infantil +transporte de cercanías +beneficio de la empresa +dental +discapacidad +tarifas +cuenta flexible para gastos (fsa, por sus siglas en inglés) +cuenta de ahorros para la salud (hsa, por sus siglas en inglés) +gastos del trabajo +crédito +seguro de vida +préstamo +seguro médico +otro +reasignación +jubilación +pago retroactivo +ahorros +acciones +impuesto +propinas +cuotas sindicales +oftalmología +embargo de salario"," %{category}: +caridad +manutención infantil +transporte de cercanías +beneficio de la empresa +dental +discapacidad +tarifas +cuenta flexible para gastos (fsa, por sus siglas en inglés) +cuenta de ahorros para la salud (hsa, por sus siglas en inglés) +gastos del trabajo +crédito +seguro de vida +préstamo +seguro médico +otro +reasignación +jubilación +pago retroactivo +ahorros +acciones +impuesto +propinas +cuotas sindicales +oftalmología +embargo de salario",Client,Yes,Payment details,,,,,,,,,,,,,,,,,,, +en.cbv.payment_details.show.employment_end_date,Employment end date,,Fecha de finalización del empleo,Fecha de finalización del empleo,Client,Yes,Payment details,,,,,,,,,,,,,,,,,,, +en.cbv.payment_details.show.employment_information_table_header,Employment information,,Información del empleo,Información del empleo,Client,Yes,Payment details,,,,,,,,,,,,,,,,,,, +en.cbv.payment_details.show.employment_start_date,Employment start date,,Fecha de inicio del empleo,Fecha de inicio del empleo,Client,Yes,Payment details,,,,,,,,,,,,,,,,,,, +en.cbv.payment_details.show.employment_status,Employment status,,Estatus del empleo,Estatus del empleo,Client,Yes,Payment details,,,,,,,,,,,,,,,,,,, +en.cbv.payment_details.show.frequency_unknown,Frequency Unknown,,Frecuencia desconocida,Frecuencia desconocida,Client,,,,,,,,,,,,,,,,,,,,, +en.cbv.payment_details.show.header,Your payment information from %{employer_name},Your payment information from [employer],Su información de pago de [empleador],Su información de pago de %{employer_name},Client,Yes,Payment details,,,,,,,,,,,,,,,,,,, +en.cbv.payment_details.show.header_no_employer_name,Your payment information from your employer,,Su información de pago por parte de su empleador,Su información de pago por parte de su empleador,Client,,,,,,,,,,,,,,,,,,,,, +en.cbv.payment_details.show.hourly_rate,Compensation amount,Compensation amount [$] [compensation amount],Monto de compensación [$] [monto de compensación],Monto de compensación,Client,Yes,Payment details,,,,,,,,,,,,,,,,,,, +,,"[Compensation amount options to translate] +annually +bi-weekly +daily +hourly +monthly +per mile +semi-monthly +semi-weekly +variable +weekly","[Opciones de monto de compensación a traducir] +anual +cada dos semanas +diario +por hora +mensual +por milla +dos veces al mes +cada dos semanas +variable +semanal","Compensation amount options: +anual +cada dos semanas +diario +por hora +mensual +por milla +dos veces al mes +dos veces a la semana +variable +semanal",Client,Yes,Payment details,,,,,,,,,,,,,,,,,,, +en.cbv.payment_details.show.none_found,No payments found.,,No se encontraron pagos.,No se encontraron pagos.,Client,Need to add,?,,,,,,,,,,,,,,,,,,, +en.cbv.payment_details.show.number_of_hours_worked,Number of hours worked,, Número de horas trabajadas,Número de horas trabajadas,Client,Yes,Payment details,,,,,,,,,,,,,,,,,,, +en.cbv.payment_details.show.pay_date,Pay Date: %{pay_date},Pay Date: ,Fecha de pago: ,Fecha de pago: %{pay_date},Client,Yes,Payment details,,,,,,,,,,,,,,,,,,, +en.cbv.payment_details.show.pay_frequency,Pay period frequency,Pay period frequncy [frequnecy],Frecuencia del período de pago [frecuencia],Frecuencia del período de pago,Client,Yes,Payment details,,,,,,,,,,,,,,,,,,, +,,"[frequency options to translate] +bi-weekly +daily +monthly +semi-monthly +variable +weekly","[opciones de frecuencia a traducir] +cada dos semanas +diario +mensual +dos veces al mes +variable +semanal","Frequency options: +cada dos semanas +diario +mensual +dos veces al mes +variable +semanal",Client,Yes,Payment details,,,,,,,,,,,,,,,,,,, +en.cbv.payment_details.show.pay_gross,Payment before taxes (gross),,Pago antes del pago de impuestos (bruto),Pago antes de impuestos (bruto),Client,Yes,Payment details,,,,,,,,,,,,,,,,,,, +en.cbv.payment_details.show.pay_gross_ytd,Gross pay YTD,,"Remuneración bruta desde el inicio del año a la fecha (YTD, por sus siglas en inglés)","Remuneración bruta desde el inicio del año a la fecha (YTD, por sus siglas en inglés)",Client,Yes,Payment details,,,,,,,,,,,,,,,,,,, +en.cbv.payment_details.show.pay_net,Payment after taxes and deductions (net),,Pago después de impuestos y deducciones (neto),Pago después de impuestos y deducciones (neto),Client,Yes,Payment details,,,,,,,,,,,,,,,,,,, +en.cbv.payment_details.show.pay_period,Pay period,,Período de pago,Período de pago,Client,Yes,Payment details,,,,,,,,,,,,,,,,,,, +en.cbv.payment_details.show.payment_hours,%{amount} hours,[#] hours,[#] de horas,%{amount} horas,Client,Yes,Payment details,,,,,,,,,,,,,,,,,,, +en.cbv.payment_details.show.payments_and_deductions_table_header,Payments and deductions,,Pagos y deducciones,Pagos y deducciones,Client,Yes,Payment details,,,,,,,,,,,,,,,,,,, +en.cbv.payment_details.show.subheader,"We have gathered your payment records from the past 90 days, from %{start_date} to %{end_date}. If the information is missing or inaccurate, add a comment for %{agency_acronym}. This information will be included in your income report.","We have gathered your payment records from the past 90 days, from [date] to [date]. If the information is missing or inaccurate, add a comment for [agency]. This information will be included in your income report.","Hemos recopilado sus registros de pago de los últimos 90 días, del [fecha] al [fecha]. Si falta información o esta es inexacta, añada un comentario para [agencia]. Esta información se incluirá en su informe de ingresos.","Hemos recopilado sus registros de pago de los últimos 90 días, del %{start_date} al %{end_date}. Si falta información o esta es inexacta, añada un comentario para %{agency_acronym}. Esta información se incluirá en su informe de ingresos.",Client,Yes,Payment details,,,,,,,,,,,,,,,,,,, +en.cbv.payment_details.show.total_gross_description,"This is the total gross income from your job before taxes, benefits and deductions were taken out of your paycheck.",,"Estos son sus ingresos brutos totales provenientes de su trabajo, antes del pago de impuestos, los beneficios y deducciones se restaron de su cheque de pago.","Estos son sus ingresos brutos totales provenientes de su trabajo, antes del pago de impuestos, beneficios y deducciones que se restaron de su cheque de pago.",Client,Yes,Payment details,,,,,,,,,,,,,,,,,,, +en.cbv.payment_details.show.total_gross_income,"Total income from the past 90 days, before taxes: %{amount}","Total income from the past 90 days, before taxes:","Ingresos totales de los últimos 90 días, antes de impuestos:","Ingresos totales de los últimos 90 días, antes de impuestos: %{amount}",Client,Yes,Payment details,,,,,,,,,,,,,,,,,,, +en.cbv.payment_details.show.unknown,Unknown,,Desconocidos,Desconocido,Client,,,,,,,,,,,,,,,,,,,,, +en.cbv.successes.show.back_to_agency,Go to %{agency_short_name} website,Go to [agency] website,Vaya al sitio web de [agencia],Vaya al sitio web de %{agency_short_name},Client,Yes,Success,,,,,,,,,,,,,,,,,,, +en.cbv.successes.show.caseworker_received,We have delivered your payment information to %{agency_acronym}. They will contact you if any additional information is needed.,We have delivered your payment information to [agency]. They will contact you if any additional information is needed.,Hemos enviado su información de pago a [agencia]. Ellos lo contactarán si se necesita alguna información adicional.,Hemos enviado su información de pago a %{agency_acronym}. Ellos lo contactarán si se necesita alguna información adicional.,Client,Yes,Success,,,,,,,,,,,,,,,,,,, +en.cbv.successes.show.check_status.default,To check the status of your SNAP application or recertification you can visit DTA's website.,,Para comprobar el estado de su solicitud o recertificación del SNAP puede visitar el sitio web del DTA.,Para comprobar el estado de su solicitud o recertificación de SNAP puede visitar el sitio web del DTA.,Client,Yes,Success,,,,,,,,,,,,,,,,,,, +en.cbv.successes.show.check_status.ma,To check the status of your SNAP recertification you can visit DTA's website.,,Para comprobar el estado de su recertificación del SNAP puede visitar el sitio web del DTA.,Para comprobar el estado de su recertificación de SNAP puede visitar el sitio web del DTA.,Client,Yes,Success,,,,,,,,,,,,,,,,,,, +en.cbv.successes.show.confirmation_code_html,Confirmation code: %{confirmation_code},Confirmation code: ,Código de confirmación ,Código de confirmación : %{confirmation_code},Client,Yes,Success,,,,,,,,,,,,,,,,,,, +en.cbv.successes.show.download,Download a copy of the report,,Descargue una copia del informe,Descargue una copia del informe,Client,Yes,Success,,,,,,,,,,,,,,,,,,, +en.cbv.successes.show.header,Your income report has been successfully shared with %{agency_acronym},Your income report has been successfully shared with [agency],Su informe de ingresos ha sido compartido de forma exitosa con [agencia],Su informe de ingresos ha sido compartido de forma exitosa con %{agency_acronym},Client,Yes,Success,,,,,,,,,,,,,,,,,,, +en.cbv.successes.show.if_it_didnt_work,"If you weren't able to find an employer, or one of your employers doesn't have an online payroll provider, please provide your payment information directly to %{agency_acronym}.","If you weren't able to find an employer, or one of your employers doesn't have an online payroll provider, please provide your payment information directly to [agency].","Si usted no logró encontrar un empleador, o uno de sus empleadores no tiene un proveedor de nómina en línea, por favor, suministre su información de pago directamente a [agencia].","Si usted no logró encontrar un empleador, o uno de sus empleadores no tiene un proveedor de nómina en línea, por favor, suministre su información de pago directamente a %{agency_acronym}.",Client,Yes,Success,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.additional_comments,Additional comments,,Comentarios adicionales,Comentarios adicionales,Client,Yes,Summary,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.additional_information_title,Is there anything else you'd like your caseworker to know about your income?,,¿Hay algo más que desea que su trabajador social sepa sobre sus ingresos?,¿Hay algo más que desea que su trabajador social sepa sobre sus ingresos?,Client,,,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.application_or_recertification_date.ma,Recertification interview date,,Fecha de la entrevista de recertificación,Fecha de la entrevista de recertificación,Client,,,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.application_or_recertification_date.nyc,Application or recertification date,,Fecha de solicitud o recertificación,Fecha de solicitud o recertificación,Client,,,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.application_or_recertification_date.sandbox,Application or recertification date,,Fecha de solicitud o recertificación,Fecha de solicitud o recertificación,Client,,,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.consent_to_authorize_use_html.ma,"Check this box to confirm that the information provided by you is true and complete to the best of your knowledge. You agree to inform DTA of any income not reflected in this report or any discrepancies found in the information gathered with this tool. You understand that providing accurate and complete information is your responsibility, and any false or omitted information may have legal consequences. For more information on your rights and responsibilities regarding private information you share with DTA, please refer to the Rights and Responsibilities you signed at application, found on Mass.gov.

    By sending this report, you authorize its use for income verification by authorized DTA personnel.","Check this box to confirm that the information provided by you is true and complete to the best of your knowledge. You agree to inform DTA of any income not reflected in this report or any discrepancies found in the information gathered with this tool. You understand that providing accurate and complete information is your responsibility, and any false or omitted information may have legal consequences. For more information on your rights and responsibilities regarding private information you share with DTA, please refer to the Rights and Responsibilities you signed at application, found on Mass.gov. By sending this report, you authorize its use for income verification by authorized DTA personnel.","Marque esta casilla para confirmar que, a su leal saber y entender, la información proporcionada por usted es verdadera y completa. Usted se compromete a informar al DTA sobre cualquier ingreso no reflejado en este informe o cualquier discrepancia hallada en la información recopilada con esta herramienta. Usted entiende que suministrar información precisa y completa es su responsabilidad, y que cualquier información falsa u omitida puede tener consecuencias legales. Para obtener más información sobre sus derechos y responsabilidades en relación a la información privada que comparte con el DTA, consulte los Derechos y Responsabilidades que firmó en la solicitud, que se encuentran en Mass.gov. Al enviar este informe, usted autoriza el uso de esta verificación de ingresos por parte de personal autorizado del DTA.","Marque esta casilla para confirmar que, a su leal saber y entender, la información proporcionada por usted es verdadera y completa. Usted se compromete a informar al DTA sobre cualquier ingreso no reflejado en este informe o cualquier discrepancia hallada en la información recopilada con esta herramienta. Usted entiende que suministrar información precisa y completa es su responsabilidad, y que cualquier información falsa u omitida puede tener consecuencias legales. Para obtener más información sobre sus derechos y responsabilidades en relación a la información privada que comparte con el DTA, consulte los Derechos y Responsabilidades que firmó en la solicitud, que se encuentran en Mass.gov.

    Al enviar este informe, usted autoriza el uso de esta verificación de ingresos por parte de personal autorizado del DTA.",Client,Yes,Summary,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.consent_to_authorize_use_html.nyc,"Check this box to confirm that the information provided by you is true and complete to the best of your knowledge. You agree to inform NYC Human Resources Administration (HRA) of any income not reflected in this report or any discrepancies found in the information gathered with this tool. You understand that providing accurate and complete information is your responsibility, and any false or omitted information may have legal consequences.

    By sending this report, you authorize its use for income verification by authorized HRA personnel.","Check this box to confirm that the information provided by you is true and complete to the best of your knowledge. You agree to inform NYC Human Resources Administration (HRA) of any income not reflected in this report or any discrepancies found in the information gathered with this tool. You understand that providing accurate and complete information is your responsibility, and any false or omitted information may have legal consequences. By sending this report, you authorize its use for income verification by authorized HRA personnel.","Marque esta casilla para confirmar que, a su leal saber y entender, la información proporcionada por usted es verdadera y completa. Usted accede a informar a la Administración de Recursos Humanos (HRA) de la Ciudad de Nueva York (NYC, por sus siglas en inglés) de cualquier ingreso no reflejado en este informe o cualquier discrepancia encontrada en la información recopilada con esta herramienta. Usted entiende que suministrar información precisa y completa es su responsabilidad, y que cualquier información falsa u omitida puede tener consecuencias legales. Al enviar este informe, autoriza su uso para la verificación de los ingresos por parte del personal autorizado de la HRA.","Marque esta casilla para confirmar que, a su leal saber y entender, la información proporcionada por usted es verdadera y completa. Usted accede a informar a la Administración de Recursos Humanos (HRA) de la Ciudad de Nueva York (NYC, por sus siglas en inglés) de cualquier ingreso no reflejado en este informe o cualquier discrepancia encontrada en la información recopilada con esta herramienta. Usted entiende que suministrar información precisa y completa es su responsabilidad, y que cualquier información falsa u omitida puede tener consecuencias legales.

    Al enviar este informe, autoriza su uso para la verificación de los ingresos por parte del personal autorizado de la HRA.",Client,Yes,Summary,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.consent_to_authorize_use_html.sandbox,"Check this box to confirm that the information provided by you is true and complete to the best of your knowledge. You agree to inform CBV Test Agency of any income not reflected in this report or any discrepancies found in the information gathered with this tool. You understand that providing accurate and complete information is your responsibility, and any false or omitted information may have legal consequences.

    By sending this report, you authorize its use for income verification by authorized CBV personnel.","Check this box to confirm that the information provided by you is true and complete to the best of your knowledge. You agree to inform CBV Test Agency of any income not reflected in this report or any discrepancies found in the information gathered with this tool. You understand that providing accurate and complete information is your responsibility, and any false or omitted information may have legal consequences. By sending this report, you authorize its use for income verification by authorized CBV personnel.","Marque esta casilla para confirmar que, a su leal saber y entender, la información proporcionada por usted es verdadera y completa. Usted se compromete a informar a la Agencia de pruebas CBV sobre cualquier ingreso no reflejado en este informe o cualquier discrepancia hallada en la información recopilada con esta herramienta. Usted entiende que suministrar información precisa y completa es su responsabilidad, y que cualquier información falsa u omitida puede tener consecuencias legales. Al enviar este informe, autoriza su uso para la verificación de los ingresos por parte del personal autorizado del CBV.","Marque esta casilla para confirmar que, a su leal saber y entender, la información proporcionada por usted es verdadera y completa. Usted se compromete a informar a la Agencia de pruebas CBV sobre cualquier ingreso no reflejado en este informe o cualquier discrepancia hallada en la información recopilada con esta herramienta. Usted entiende que suministrar información precisa y completa es su responsabilidad, y que cualquier información falsa u omitida puede tener consecuencias legales.

    Al enviar este informe, autoriza su uso para la verificación de los ingresos por parte del personal autorizado del CBV.",Client,No,Summary,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.consent_to_authorize_use_title,Legal Agreement,,Acuerdo legal,Acuerdo legal,Client,Yes,Summary,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.description,"The report below has your income from the past 90 days from, from %{start_date} to %{end_date}. Please review it before you send it to %{agency_acronym}.","The report below has your income from the past 90 days from, from [date] to [date]. Please review it before you send it to [agency].","El siguiente informe contiene sus ingresos de los últimos 90 días, del [fecha] al [fecha]. Revíselo antes de enviarlo a [agency].","El siguiente informe contiene sus ingresos de los últimos 90 días, del %{start_date} al %{end_date}. Revíselo antes de enviarlo a %{agency_acronym}.",Client,Yes,Summary,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.header,Review and submit your income report,,Revise y presente su informe de ingresos,Revise y presente su informe de ingresos,Client,Yes,Summary,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.none_found,No payments found. Please refresh the page after a few minutes.,,No se encontraron pagos. Refresque la página después de unos minutos.,No se encontraron pagos. Actualice la página después de unos minutos.,Client,,,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.payment,Payment of %{amount} before taxes on %{date},Payment of [$] before taxes on [date],Pago de [$] antes de impuestos el [fecha],Pago de %{amount} antes de pago impuestos en %{date},Client,Yes,Summary,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.pdf.caseworker.agreement_consent_timestamp,Agreement Consent Timestamp,,Marca de tiempo del acuerdo de consentimiento,Marca de tiempo del acuerdo de consentimiento,Staff,No need for translation,Income report,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.pdf.caseworker.case_number,Case number,,Número de caso,Número de caso,Staff,No need for translation,,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.pdf.caseworker.client_email_address,Client's email address,,Dirección de correo electrónico del cliente,Dirección de correo electrónico del cliente,Staff,No need for translation,,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.pdf.caseworker.client_full_name,Client full name (linked to payroll account),,Nombre completo del cliente (vinculado a la cuenta de nómina),Nombre completo del cliente (vinculado a la cuenta de nómina),Staff,No need for translation,,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.pdf.caseworker.client_id_number,CIN,,CIN,CIN,Staff,No need for translation,,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.pdf.caseworker.description,The following income information was retrieved with the client's consent and has been submitted by them to their benefits agency. The client is also able to download a client-facing copy of this report.,,La siguiente información de ingresos fue obtenida con el consentimiento del cliente y ha sido presentada por este a su agencia de beneficios. El cliente también puede descargar una copia de este informe para el cliente.,La siguiente información de ingresos fue obtenida con el consentimiento del cliente y ha sido presentada por este a su agencia de beneficios. El cliente también puede descargar una versión de este informe.,Staff,No need for translation,,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.pdf.caseworker.first_name,Client's first name,,Nombre del cliente,Nombre del cliente,Staff,No need for translation,,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.pdf.caseworker.how_to,"This report includes payment information from the past 90 days. In most cases, you only need to review income from the last 30 days for eligibility purposes. Use data beyond the 30-day period only if necessary. Key fields for income verification are highlighted in yellow.",,"Este informe incluye información de pago de los últimos 90 días. En la mayoría de los casos, solo hay que revisar los ingresos de los últimos 30 días con fines de (determinación de) la elegibilidad. Use los datos posteriores al período de 30 días solo si es necesario. Los campos clave para la verificación de los ingresos aparecen resaltados en amarillo.","Este informe incluye información de pago de los últimos 90 días. En la mayoría de los casos, solo hay que revisar los ingresos de los últimos 30 días con fines de (determinación de) la elegibilidad. Use los datos posteriores al período de 30 días solo si es necesario. Los campos clave para la verificación de los ingresos aparecen resaltados en amarillo.",Staff,No need for translation,,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.pdf.caseworker.how_to_header,How to use this report:,,Cómo usar este informe:,Cómo usar este informe:,Staff,No need for translation,,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.pdf.caseworker.last_name,Client's last name,,Apellido del cliente,Apellido del cliente,Staff,No need for translation,,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.pdf.caseworker.middle_name,Client's middle name,,Segundo nombre del cliente,Segundo nombre del cliente,Staff,No need for translation,,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.pdf.caseworker.pay_period,Pay period (%{pay_frequency}),Pay period ([pay frequency]),Período de pago ([frecuencia de pago]),Período de pago (%{pay_frequency}),Client,Yes,Income report,,,,,,,,,,,,,,,,,,, +,,"[frequency options to translate] +bi-weekly +daily +monthly +semi-monthly +variable +weekly","[opciones de frecuencia a traducir] +cada dos semanas +diario +mensual +dos veces al mes +variable +semanal","%{pay_frequency}: +cada dos semanas +diario +mensual +dos veces al mes +variable +semanal",Client,Yes,Income report,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.pdf.caseworker.snap_agency_id,SNAP Agency ID,,Identificación de la agencia del SNAP,Identificación de la agencia de SNAP,Staff,No need for translation,,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.pdf.caseworker.staff_beacon_id_wel_id,Staff BEACON ID (WELID),,,Staff BEACON ID (WELID),Staff,No need for translation,,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.pdf.client.address,Employer address,,Dirección del empleador,Dirección del empleador,Client,Yes,Income report,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.pdf.client.agency_id_number,Client's Agency ID,,Identificación de la agencia del cliente,Identificación de la agencia del cliente,Staff,No need for translation,Income report,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.pdf.client.client_report_information,Client and Report Information,,Información sobre el cliente y el informe,Información sobre el cliente y el informe,Client,Yes,Income report,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.pdf.client.date_created,Date the income report was created,,Fecha en que se creó el informe de ingresos,Fecha en que se creó el informe de ingresos,Client,Yes,Income report,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.pdf.client.date_range,Date range for the income report,,Intervalo de fechas para el informe de ingresos,Intervalo de fechas para el informe de ingresos,Client,Yes,Income report,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.pdf.client.description,We have collected your income information with your consent and sent it to your SNAP agency. Any additional income that you weren't able to add to this report should be shared separately with your SNAP agency.,,Hemos recopilado su información de ingresos con su consentimiento y la hemos enviado a su agencia del SNAP. Cualquier ingreso adicional que no haya logrado agregar a este informe debe compartirlo por separado con su agencia SNAP.,Hemos recopilado su información de ingresos con su consentimiento y la hemos enviado a su agencia de SNAP. Cualquier ingreso adicional que no haya logrado agregar a este informe debe compartirlo por separado con su agencia de SNAP.,Client,Yes,Income report,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.pdf.client.employment_payment_details,Employment and Payment details,,Datos de empleo y pago,Datos de empleo y pago,Client,Yes,Income report,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.pdf.client.header,Income Verification Report,,Informe de verificación de ingresos,Informe de verificación de ingresos,Client,Yes,Income report,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.pdf.shared.confirmation_code,Confirmation code,,Código de confirmación,Código de confirmación,Client,Yes,Income report,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.phone_number,Employer phone,,Teléfono del empleador,Teléfono del empleador,Client,Yes,Income report,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.send_report,Share my report with %{agency_acronym},Share my report with [agency],Comparta mi informe con [agencia],Comparta mi informe con %{agency_acronym},Client,,Summary ,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.table_caption,Employer %{number}: %{employer_name},Employer [#]:,Empleador [#]:,Empleador %{number}: %{employer_name},Client,Yes,Income report,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.table_caption_no_name,Employer %{number},Employer [#]:,Empleador [#]:,Empleador %{number}:,Client,Yes,Income report,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.total_income_from,Total income from %{employer_name} before taxes: %{amount},Total income from [employer] before taxes: ,"Ingresos totales provenientes de [empleador], antes del pago de impuestos: ","Ingresos totales provenientes de %{employer_name}, antes del pago de impuestos: %{amount}",Client,,,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.total_income_from_no_employer_name,Total income before taxes: %{amount},Total income before taxes: ,Ingresos totales antes de impuestos: ,Ingresos totales antes del pago de impuestos: %{amount},Client,,,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.total_payments,"Total income from the past 90 days, before taxes: %{amount}","Total income from the past 90 days, before taxes:","Ingresos totales de los últimos 90 días, antes del pago de impuestos:","Ingresos totales de los últimos 90 días, antes del pago de impuestos: %{amount}",Client,,,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.show.total_payments_desc,"This is the total gross income from your job(s) before taxes, benefits and deductions were taken out of your paycheck.",,,"Este es el ingreso bruto total de su(s) trabajo(s) antes de que se le descuenten impuestos, beneficios y otras deducciones de su cheque.",Client,,,,,,,,,,,,,,,,,,,,, +en.cbv.summaries.update.consent_to_authorize_warning,You must check the legal agreement checkbox to proceed.,,,Debe marcar la casilla de acuerdo legal para proceder.,Client,,,,,,,,,,,,,,,,,,,,, +en.pages.home.description_1,The SNAP Income Pilot is a new tool designed to help you connect your income details from your employer or payroll provider directly to your SNAP agency. We're currently testing this tool to ensure it works effectively.,,,El SNAP Income Pilot es una nueva herramienta diseñada para ayudarle a conectar los detalles de sus ingresos de su empleador o proveedor de nómina directamente con su agencia de SNAP. Actualmente estamos probando esta herramienta para asegurarnos de que funcione de manera eficaz.,Client,,,,,,,,,,,,,,,,,,,,, +en.pages.home.description_2,Please note this pilot is currently available only to SNAP participants in New York City and Massachusetts.,,,Tenga en cuenta que este piloto está disponible actualmente solo para los participantes de SNAP en la ciudad de Nueva York y Massachusetts.,Client,,,,,,,,,,,,,,,,,,,,, +en.pages.home.description_3_html,"

    To participate, you can request an invitation from your SNAP agency:

    ","To participate, you can request an invitation from your SNAP agency: +Massachusetts applicants: Contact the Department of Transitional Assistance (DTA) +New York City applicants: Contact the Human Resources Administration (HRA)","Para participar, puede solicitar una invitación a su agencia del SNAP: +Solicitantes de Massachusetts: Contactar al Departamento de Asistencia Transitoria (DTA) +Solicitantes de la Ciudad de Nueva York: Contactar a la Administración de Recursos Humanos (HRA)","

    Para participar, puede solicitar una invitación a su agencia del SNAP:

    ",Client,,,,,,,,,,,,,,,,,,,,, +en.pages.home.header,Welcome to the SNAP Income Pilot,,Bienvenido a SNAP Income Pilot,Bienvenido al SNAP Income Pilot,Client,,,,,,,,,,,,,,,,,,,,, +en.shared.agency_full_name.ma,Massachusetts Department of Transitional Assistance,,Departamento de Asistencia Transitoria de Massachusetts,Departamento de Asistencia Transitoria de Massachusetts,Client,,,,,,,,,,,,,,,,,,,,, +en.shared.agency_full_name.nyc,New York City Human Resources Administration,,Administración de Recursos Humanos de la Ciudad de Nueva York,,Client,,,,,,,,,,,,,,,,,,,,, +en.shared.agency_full_name.sandbox,CBV Test Agency,,Agencia de pruebas CBV,Agencia de pruebas CBV,Client,,,,,,,,,,,,,,,,,,,,, +en.shared.app_name.ma,DTA Connect,,DTA Connect,DTA Connect,Client,,,,,,,,,,,,,,,,,,,,, +en.shared.app_name.nyc,ACCESS HRA,,ACCESS HRA,ACCESS HRA,Client,,,,,,,,,,,,,,,,,,,,, +en.shared.app_name.sandbox,CBVApp,,CBVApp,CBVApp,Client,,,,,,,,,,,,,,,,,,,,, +en.shared.banner.lock,Lock,,Candado,Candado,Client,,,,,,,,,,,,,,,,,,,,, +en.shared.banner.locked_padlock,A locked padlock,,Un candado cerrado,Un candado cerrado,Client,,,,,,,,,,,,,,,,,,,,, +en.shared.error_unauthorized,The URL you're accessing is forbidden for the current user. Please verify you are logged in as the correct user and try accessing the URL again.,,La URL a la que estás accediendo está prohibida para el usuario actual. Verifique que está conectado como el usuario correcto e intente acceder de nuevo a la URL.,La URL a la que estás accediendo está prohibida para el usuario actual. Verifique que está conectado como el usuario correcto e intente acceder de nuevo a la URL.,Client,,,,,,,,,,,,,,,,,,,,, +en.shared.footer.feedback,Report feedback or bugs,,Notifique comentarios o errores,Notifique comentarios o errores,Client,,,,,,,,,,,,,,,,,,,,, +en.shared.header.aria_label,Main navigation,,Menú principal,Menú principal,Client,,,,,,,,,,,,,,,,,,,,, +en.shared.header.cbv_flow_title.ma,Department of Transitional Assistance,,Departamento de Asistencia Transitoria,Departamento de Asistencia Transitoria,Client,,,,,,,,,,,,,,,,,,,,, +en.shared.header.cbv_flow_title.nyc,Human Resources Administration,,Administración de Recursos Humanos,Administración de Recursos Humanos,Client,,,,,,,,,,,,,,,,,,,,, +en.shared.header.cbv_flow_title.sandbox,CBV Test Agency,,Agencia de pruebas CBV,Agencia de pruebas CBV,Client,,,,,,,,,,,,,,,,,,,,, +en.shared.header.close,Close,,Cerrar,Cerrar,Client,,,,,,,,,,,,,,,,,,,,, +en.shared.header.log_out,Log out,,Cerrar sesión,Cerrar sesión,Client,,,,,,,,,,,,,,,,,,,,, +en.shared.header.preheader.default,A website in partnership with CBV Test Agency.,,Un sitio web en colaboración con la Agencia de pruebas CBV.,Un sitio web en colaboración con la Agencia de pruebas CBV.,Client,,,,,,,,,,,,,,,,,,,,, +en.shared.header.preheader.ma,A website in partnership with the Commonwealth of Massachusetts.,,Un sitio web en colaboración con el Estado de Massachusetts.,Un sitio web en colaboración con el Estado de Massachusetts.,Client,,,,,,,,,,,,,,,,,,,,, +en.shared.header.preheader.nyc,A website in partnership with the City of New York.,,Un sitio web en colaboración con la Ciudad de Nueva York.,Un sitio web en colaboración con la Ciudad de Nueva York.,Client,,,,,,,,,,,,,,,,,,,,, +en.shared.header.primary,Primary navigation,,Menú principal,Menú principal,Client,,,,,,,,,,,,,,,,,,,,, +en.shared.languages.en,English,,Inglés,Inglés,Client,,,,,,,,,,,,,,,,,,,,, +en.shared.languages.es,Español,,Español,Español,Client,,,,,,,,,,,,,,,,,,,,, +en.shared.languages.fr,Français,,Francés,Francés,Client,,,,,,,,,,,,,,,,,,,,, +en.shared.languages.zh,??,,Chino,Chino,Client,,,,,,,,,,,,,,,,,,,,, +en.shared.not_applicable,N/A,,N/C,N/C,Client,,,,,,,,,,,,,,,,,,,,, +en.shared.pilot_name,SNAP Income Pilot,,SNAP Income Pilot,SNAP Income Pilot,Client,,,,,,,,,,,,,,,,,,,,, +en.shared.skip_link,Skip to main content,,Saltar al contenido principal,Saltar al contenido principal,Client,,,,,,,,,,,,,,,,,,,,, +en.us_form_with.boolean_false,No,,No,No,Client,,,,,,,,,,,,,,,,,,,,, +en.us_form_with.boolean_true,Yes,,Sí,Sí,Client,,,,,,,,,,,,,,,,,,,,, +en.us_form_with.date_picker_format,Format: mm/dd/yyyy,,Formato: mm/dd/aaaa,Formato: mm/dd/aaaa,Client,,,,,,,,,,,,,,,,,,,,, +en.us_form_with.optional,Optional,,Opcional,Opcional,Client,,,,,,,,,,,,,,,,,,,,, +en.users.omniauth_callbacks.authentication_successful,You are signed in.,,Ha iniciado sesión.,Ha iniciado sesión.,Client,,,,,,,,,,,,,,,,,,,,, diff --git a/app/spec/support/fixtures/pinwheel/request_platform_response.json b/app/spec/support/fixtures/pinwheel/request_platform_response.json new file mode 100644 index 00000000..e1b6e139 --- /dev/null +++ b/app/spec/support/fixtures/pinwheel/request_platform_response.json @@ -0,0 +1,26 @@ +{ + "data": { + "id": "00000000-0000-0000-0000-000000011111", + "name": "Testing Payroll Provider Inc.", + "type": "payroll", + "fractional_amount_supported": false, + "min_amount": null, + "max_amount": null, + "last_updated": "2023-05-05T15:18:39.312868+00:00", + "logo_url": null, + "percentage_supported": false, + "min_percentage": 1, + "max_percentage": 99, + "supported_jobs": [ + "direct_deposit_allocations", + "income", + "identity", + "employment", + "tax_forms", + "direct_deposit_switch", + "paystubs", + "shifts" + ], + "amount_supported": true + } +} diff --git a/app/spec/support/pinwheel_api_helper.rb b/app/spec/support/pinwheel_api_helper.rb index 543d6f4f..0e74c26c 100644 --- a/app/spec/support/pinwheel_api_helper.rb +++ b/app/spec/support/pinwheel_api_helper.rb @@ -112,6 +112,15 @@ def stub_request_identity_response ) end + def stub_request_platform_response + stub_request(:get, %r{#{PinwheelService::PLATFORMS_ENDPOINT}/[0-9a-fA-F\-]{36}}) + .to_return( + status: 200, + body: load_relative_json_file('request_platform_response.json').to_json, + headers: { 'Content-Type': 'application/json;charset=UTF-8' } + ) + end + def load_relative_file(filename) File.read(File.join( File.dirname(__FILE__),