Skip to content
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
1bafab4
Add new contract model
polypixeldev Nov 11, 2025
4cef2f8
Factor out invite relation into the contractable polymorphic relation…
polypixeldev Nov 11, 2025
77cc7ce
Replace other usages of OrganizerPosition::Contract
polypixeldev Nov 11, 2025
474be6e
Rename references to organizer_position_contract
polypixeldev Nov 11, 2025
cb8dbdd
Rename controller and view
polypixeldev Nov 11, 2025
893401e
Rename opc_params object
polypixeldev Nov 11, 2025
0a66aff
Rename path helpers
polypixeldev Nov 11, 2025
be297ba
Remove old contracts mailer
polypixeldev Nov 11, 2025
700acb3
Rename remaining usage of contract.opi
polypixeldev Nov 11, 2025
02b4872
Copy over records in db migration
polypixeldev Nov 12, 2025
0db93f3
Fix model and migration
polypixeldev Nov 12, 2025
ef63d31
Fix use of contract.opi_id
polypixeldev Nov 12, 2025
cbde0c5
Fix undefined instance variable
polypixeldev Nov 12, 2025
f84f606
Move contract mailers
polypixeldev Nov 12, 2025
c1571e7
Reset pk sequence for contracts after migration
polypixeldev Nov 12, 2025
ae8a528
Move contract policy
polypixeldev Nov 12, 2025
987421e
Rename ContractPolicy
polypixeldev Nov 12, 2025
00fc45b
Fix sending contracts for existing members
polypixeldev Nov 12, 2025
a43ca31
Merge branch 'main' into polypixeldev/new-contract-model
polypixeldev Nov 12, 2025
e0ee624
Merge branch 'main' into polypixeldev/new-contract-model
polypixeldev Nov 17, 2025
9ce83bd
Rename opc to contract in controller
polypixeldev Nov 17, 2025
c18535b
Remove redundant batches setting
polypixeldev Nov 17, 2025
33f5dfe
Make one_non_void_contract validation private
polypixeldev Nov 18, 2025
10dd5f6
Wrap db updates in send_contract method in transaction
polypixeldev Nov 18, 2025
2cfac02
Move set airtable status within transaction
polypixeldev Nov 18, 2025
4150a1e
Remove unnecessary transaction
polypixeldev Nov 18, 2025
fc48eec
Add note about reset_pk_sequence
polypixeldev Nov 18, 2025
93b8b60
Use relations to improve Contractable performance
polypixeldev Nov 22, 2025
44ccbe2
Remove override guards in Contractable
polypixeldev Nov 23, 2025
8344c06
Add STI to contracts table
polypixeldev Nov 23, 2025
8e56fe4
Merge branch 'main' into polypixeldev/new-contract-model
polypixeldev Nov 23, 2025
f29816c
Fix STI implementation
polypixeldev Nov 23, 2025
c3f9b90
Add relation to contract from organizer position
polypixeldev Nov 23, 2025
b872564
Disable ddl transaction
polypixeldev Nov 23, 2025
cbc3e9d
Add contract reference to op
polypixeldev Nov 23, 2025
0b9024e
Fix migration
polypixeldev Nov 23, 2025
47e5def
Merge branch 'main' into polypixeldev/new-contract-model
polypixeldev Nov 23, 2025
ce6fa21
Undo schema change
polypixeldev Nov 23, 2025
41d4a9d
Rename contract reference to fiscal sponsorship contract
polypixeldev Nov 23, 2025
b8a821d
Add validation to make sure fs contract is a fiscal sponsorship contract
polypixeldev Nov 23, 2025
5550428
Various small fixes
polypixeldev Nov 23, 2025
844f5cc
Discard testing template id
polypixeldev Nov 23, 2025
174ed22
Remove testing code
polypixeldev Nov 23, 2025
0263d02
Fix typo
garyhtou Nov 23, 2025
b630365
Add comment about `create` action usage
garyhtou Nov 23, 2025
6f62552
Fix FS contract validation
polypixeldev Nov 23, 2025
d52372d
Add prefills jsonb to contract
polypixeldev Nov 23, 2025
d24c2a5
Move OP contracts backfill into a one time job
polypixeldev Nov 25, 2025
47bc8de
Use string keys in prefill jsonb
polypixeldev Nov 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions app/controllers/contracts_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# frozen_string_literal: true

class ContractsController < ApplicationController
before_action :set_opc, only: [:void, :resend_to_user, :resend_to_cosigner]

def create
@contract = Contract.new(opc_params)
authorize @contract
@contract.save!
flash[:success] = "Contract sent succesfully."
redirect_back(fallback_location: event_team_path(@contract.event))
end

def void
authorize @contract
@contract.mark_voided!
flash[:success] = "Contract voided succesfully."
redirect_back(fallback_location: event_team_path(@contract.event))
end

def resend_to_user
authorize @contract

ContractMailer.with(contract: @contract).notify.deliver_later

flash[:success] = "Contract resent to user succesfully."
redirect_back(fallback_location: event_team_path(@contract.event))
end

def resend_to_cosigner
authorize @contract

if @contract.cosigner_email.present?
ContractMailer.with(contract: @contract).notify_cosigner.deliver_later
flash[:success] = "Contract resent to cosigner succesfully."
else
flash[:error] = "This contract has no cosigner."
end

redirect_back(fallback_location: event_team_path(@contract.event))
end

private

def set_opc
@contract = Contract.find(params[:id])
end

def opc_params
params.require(:contract).permit(:contractable_id, :contractable_type, :cosigner_email, :include_videos)
end

end
12 changes: 6 additions & 6 deletions app/controllers/docuseal_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class DocusealController < ActionController::Base

def webhook
ActiveRecord::Base.transaction do
contract = OrganizerPosition::Contract.find_by(external_id: params[:data][:submission_id])
contract = Contract.find_by(external_id: params[:data][:submission_id])
return render json: { success: true } unless contract # sometimes contracts are sent using Docuseal that aren't in HCB

return render json: { success: false } unless request.headers["X-Docuseal-Secret"] == Credentials.fetch(:DOCUSEAL, :WEBHOOK_SECRET)
Expand All @@ -17,8 +17,8 @@ def webhook
return render json: { success: true } if contract.signed?

document = Document.new(
event: contract.organizer_position_invite.event,
name: "Fiscal sponsorship contract with #{contract.organizer_position_invite.user.name}"
event: contract.event,
name: "Fiscal sponsorship contract with #{contract.user.name}"
)

response = Faraday.get(params[:data][:documents][0][:url]) do |req|
Expand All @@ -30,18 +30,18 @@ def webhook
filename: "#{params[:data][:documents][0][:name]}.pdf"
)

document.user = User.find_by(email: params[:data][:email]) || contract.organizer_position_invite.event.point_of_contact
document.user = User.find_by(email: params[:data][:email]) || contract.event.point_of_contact
document.save!
contract.update(document:)
contract.mark_signed!
elsif params[:event_type] == "form.declined"
contract.mark_voided!
elsif cosigner.present? && cosigner["status"] != "completed"
# send email about cosigner needing to pay
OrganizerPosition::ContractsMailer.with(contract:).pending_cosigner.deliver_later
ContractMailer.with(contract:).pending_cosigner.deliver_later
elsif signee["status"] == "completed" && (cosigner.nil? || cosigner["status"] == "completed")
# send email about hcb needing to sign
OrganizerPosition::ContractsMailer.with(contract:).pending_hcb.deliver_later
ContractMailer.with(contract:).pending_hcb.deliver_later
end
end
rescue => e
Expand Down
53 changes: 0 additions & 53 deletions app/controllers/organizer_position_contracts_controller.rb

This file was deleted.

2 changes: 1 addition & 1 deletion app/controllers/organizer_position_invites_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def create

if service.run
if @invite.is_signee
OrganizerPosition::Contract.create!(organizer_position_invite: @invite, cosigner_email: invite_params[:cosigner_email].presence, include_videos: invite_params[:include_videos])
@invite.send_contract(cosigner_email: invite_params[:cosigner_email].presence, include_videos: invite_params[:include_videos])
end
flash[:success] = "Invite successfully sent to #{user_email}"
redirect_to event_team_path @invite.event
Expand Down
28 changes: 28 additions & 0 deletions app/mailers/contract_mailer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# frozen_string_literal: true

class ContractMailer < ApplicationMailer
def notify
@contract = params[:contract]

mail to: @contract.user.email_address_with_name, subject: "You've been invited to sign a contract for #{@contract.event.name} on HCB 📝"
end

def notify_cosigner
@contract = params[:contract]

mail to: @contract.cosigner_email, subject: "You've been invited to sign a contract for #{@contract.event.name} on HCB 📝"
end

def pending_cosigner
@contract = params[:contract]

mail to: @contract.user.email_address_with_name, subject: "We're waiting for your cosigner to sign your HCB contract 📝"
end

def pending_hcb
@contract = params[:contract]

mail to: @contract.user.email_address_with_name, subject: "We're processing your HCB contract 📝"
end

end
31 changes: 0 additions & 31 deletions app/mailers/organizer_position/contracts_mailer.rb

This file was deleted.

34 changes: 34 additions & 0 deletions app/models/concerns/contractable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# frozen_string_literal: true

module Contractable
extend ActiveSupport::Concern

included do
has_many :contracts, as: :contractable, dependent: :destroy

def on_contract_signed
# This method is a callback that can be overwritten in specific classes
nil
end

def on_contract_voided
# This method is a callback that can be overwritten in specific classes
nil
end

def contract_docuseal_template_id
# This method should be overwritten in specific classes
raise NotImplementedError, "The #{self.class.name} model includes Contractable, but hasn't implemented its own version of contract_docuseal_template_id."
end

def contract_user
# This method should be overwritten in specific classes
raise NotImplementedError, "The #{self.class.name} model includes Contractable, but hasn't implemented its own version of contract_user."
end

def contract_event
# This method should be overwritten in specific classes
raise NotImplementedError, "The #{self.class.name} model includes Contractable, but hasn't implemented its own version of contract_event."
end
end
end
Loading
Loading