Skip to content

Commit 63c6f8a

Browse files
committed
Add expense creation and approval process for vendors in ProjectAllocation
1 parent 5bad6aa commit 63c6f8a

File tree

1 file changed

+70
-1
lines changed

1 file changed

+70
-1
lines changed

app/models/project_allocation.rb

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,11 @@ def payout
9292
elsif approved_funding_source?
9393
puts " Sending to approved funding source: #{funding_source.url}"
9494
proxy_collective = find_or_create_proxy_collective(funding_source.url)
95+
proxy_collective.set_payout_method
9596
if proxy_collective
9697
puts " Adding funds to proxy collective: #{proxy_collective.slug}"
97-
send_draft_expense_invitation_to_collective(proxy_collective.slug, amount_cents, proxy_collective_expense_invite_description(proxy_collective))
98+
expense = send_expense_to_vendor(proxy_collective, amount_cents)
99+
expense.approve_expense
98100
update!(paid_at: Time.now)
99101
end
100102
elsif project && project.contact_email.present?
@@ -357,6 +359,73 @@ def send_draft_expense_invitation_to_collective(collective_slug, amount_cents, d
357359
end
358360
end
359361

362+
def send_expense_to_vendor(vendor, amount_cents)
363+
return if funding_rejected?
364+
return if paid?
365+
366+
description = proxy_collective_expense_invite_description(vendor)
367+
368+
query = <<-GQL
369+
mutation(
370+
$account: AccountReferenceInput!,
371+
$expense: ExpenseCreateInput!,
372+
) {
373+
createExpense(
374+
account: $account,
375+
expense: $expense,
376+
) {
377+
id
378+
status
379+
draftKey
380+
amount
381+
currency
382+
description
383+
legacyId
384+
payee {
385+
... on Collective {
386+
slug
387+
}
388+
}
389+
}
390+
}
391+
GQL
392+
393+
variables = {
394+
account: { slug: fund.oc_project_slug }, # Collective initiating the expense draft
395+
expense: {
396+
description: expense_invite_title,
397+
longDescription: description,
398+
currency: "USD",
399+
type: "INVOICE",
400+
items: [{ amount: amount_cents, description: description }],
401+
payee: {
402+
slug: vendor.slug
403+
},
404+
payoutMethod: { type: "ACCOUNT_BALANCE" } # Specify payout method, adjust if needed
405+
}
406+
}
407+
payload = { query: query, variables: variables }.to_json
408+
409+
response = Faraday.post(
410+
"https://#{ENV['OPENCOLLECTIVE_DOMAIN']}/api/graphql/v2?personalToken=#{ENV['OPENCOLLECTIVE_TOKEN']}",
411+
payload,
412+
{ 'Content-Type' => 'application/json' }
413+
)
414+
415+
response_body = JSON.parse(response.body)
416+
417+
if response_body['errors']
418+
puts "Error: #{response_body['errors']}"
419+
else
420+
puts "Draft expense created successfully and invitation sent:"
421+
puts JSON.pretty_generate(response_body['data']['createExpense'])
422+
response_body['data']['createExpense']
423+
pp response_body
424+
# TODO this doesn't record the invitation id
425+
Invitation.create!(project_allocation: self, email: project.contact_email, status: 'DRAFT', member_invitation_id: response_body['data']['createExpense']['legacyId'], data: response_body['data']['createExpense'])
426+
end
427+
end
428+
360429
def check_collective_existence(slug)
361430
query = <<-GQL
362431
query($slug: String!) {

0 commit comments

Comments
 (0)