feat(dossier): add dossier transfer models

This commit is contained in:
Paul Chavard 2021-09-07 10:36:09 +02:00
parent dfafc57bb9
commit d6cbdf2a48
8 changed files with 159 additions and 0 deletions

View file

@ -157,6 +157,15 @@ class DossierMailer < ApplicationMailer
end
end
def notify_transfer(transfer)
I18n.with_locale(transfer.user_locale) do
@subject = default_i18n_subject(count: transfer.dossiers.count)
@transfer = transfer
mail(to: transfer.email, subject: @subject)
end
end
protected
# This is an override of `default_i18n_subject` method

View file

@ -27,6 +27,7 @@
# termine_close_to_expiration_notice_sent_at :datetime
# created_at :datetime
# updated_at :datetime
# dossier_transfer_id :bigint
# groupe_instructeur_id :bigint
# revision_id :bigint
# user_id :integer
@ -122,6 +123,9 @@ class Dossier < ApplicationRecord
has_many :types_de_champ, through: :revision
has_many :types_de_champ_private, through: :revision
belongs_to :transfer, class_name: 'DossierTransfer', foreign_key: 'dossier_transfer_id', optional: true, inverse_of: :dossiers, dependent: :destroy
has_many :transfer_logs, class_name: 'DossierTransferLog', dependent: :destroy
accepts_nested_attributes_for :champs
accepts_nested_attributes_for :champs_private

View file

@ -0,0 +1,53 @@
# == Schema Information
#
# Table name: dossier_transfers
#
# id :bigint not null, primary key
# email :string not null
# created_at :datetime not null
# updated_at :datetime not null
#
class DossierTransfer < ApplicationRecord
has_many :dossiers, dependent: :nullify
EXPIRATION_LIMIT = 2.weeks
scope :pending, -> { where('created_at > ?', (Time.zone.now - EXPIRATION_LIMIT)) }
scope :stale, -> { where('created_at < ?', (Time.zone.now - EXPIRATION_LIMIT)) }
scope :with_dossiers, -> { joins(:dossiers) }
after_create_commit :send_notification
def self.initiate(email, dossiers)
create(email: email, dossiers: dossiers)
end
def self.accept(id, current_user)
transfer = pending.find_by(id: id, email: current_user.email)
if transfer && transfer.dossiers.present?
Invite
.where(dossier: transfer.dossiers, email: transfer.email)
.destroy_all
DossierTransferLog.create(transfer.dossiers.map do |dossier|
{
dossier: dossier,
from: dossier.user.email,
to: transfer.email
}
end)
transfer.dossiers.update_all(user_id: current_user.id)
transfer.destroy
end
end
def user_locale
User.find_by(email: email)&.locale || I18n.default_locale
end
private
def send_notification
DossierMailer.notify_transfer(self).deliver_later
end
end

View file

@ -0,0 +1,14 @@
# == Schema Information
#
# Table name: dossier_transfer_logs
#
# id :bigint not null, primary key
# from :string not null
# to :string not null
# created_at :datetime not null
# updated_at :datetime not null
# dossier_id :bigint not null
#
class DossierTransferLog < ApplicationRecord
belongs_to :dossier
end

View file

@ -0,0 +1,9 @@
- content_for(:title, "#{@subject}")
%p= t(:hello, scope: [:views, :shared, :greetings])
%p
= t('.body', count: @transfer.dossiers.count)
= link_to t('.transfer_link'), dossiers_url(statut: 'dossiers-transferes')
= render partial: "layouts/mailers/signature"

View file

@ -0,0 +1,12 @@
fr:
dossier_mailer:
notify_transfer:
subject:
one: Une demande de transfert de dossier vous est adressée
other: Une demande de transfert de dossiers vous est adressée
transfer_link: demande de transfer
body:
one: |
Accéder à la demande de transfert du dossier en cliquant sur le lien suivant :
other: |
Accéder à la demande de transfert de %{count} dossiers en cliquant sur le lien suivant :

View file

@ -69,6 +69,10 @@ class DossierMailerPreview < ActionMailer::Preview
DossierMailer.notify_brouillon_not_submitted(draft)
end
def notify_transfer
DossierMailer.notify_transfer(transfer)
end
private
def usager_email
@ -111,4 +115,8 @@ class DossierMailerPreview < ActionMailer::Preview
horaires: 'Du lundi au vendredi, de 9 h à 18 h'
)
end
def transfer
DossierTransfer.new(email: usager_email, dossiers: [dossier, dossier_accepte])
end
end

View file

@ -0,0 +1,50 @@
require 'rails_helper'
RSpec.describe DossierTransfer, type: :model do
let(:user) { create(:user) }
let(:other_user) { create(:user) }
let(:dossier) { create(:dossier, user: user) }
describe 'initiate' do
subject { DossierTransfer.initiate(other_user.email, [dossier]) }
it 'should send transfer request' do
expect(subject.email).to eq(other_user.email)
expect(subject.dossiers).to eq([dossier])
expect(dossier.transfer).to eq(subject)
expect(dossier.user).to eq(user)
expect(dossier.transfer_logs.count).to eq(0)
end
describe 'accept' do
let(:transfer_log) { dossier.transfer_logs.first }
before do
DossierTransfer.accept(subject.id, other_user)
dossier.reload
end
it 'should transfer dossier' do
expect(DossierTransfer.count).to eq(0)
expect(dossier.transfer).to be_nil
expect(dossier.user).to eq(other_user)
expect(dossier.transfer_logs.count).to eq(1)
expect(transfer_log.dossier).to eq(dossier)
expect(transfer_log.from).to eq(user.email)
expect(transfer_log.to).to eq(other_user.email)
end
end
describe 'with_dossiers' do
before { subject }
it { expect(DossierTransfer.with_dossiers.count).to eq(1) }
context "when dossier discarded" do
before { dossier.discard! }
it { expect(DossierTransfer.with_dossiers.count).to eq(0) }
end
end
end
end