Commit e1bdf8b
Add monthly dividend report CSV job (#431)
# Add monthly dividend report CSV job
## Summary
This PR implements a new monthly dividend report system that
automatically generates and emails CSV reports of dividend payment data
to accounting recipients. The implementation follows the existing
consolidated invoice CSV pattern but focuses specifically on dividend
data without recipient names.
**Key Components:**
- `DividendReportCsv` service generates CSV reports with client-level
dividend summaries
- `DividendReportCsvEmailJob` Sidekiq job runs monthly on the 1st at 4
PM UTC
- CSV includes: dates, client names, total dividends, Flexile fees (2.9%
+ 30¢ capped at $30), transfer fees, ACH pull amounts
- Emails sent to Steven Olson and Howard Yu (updated per GitHub
comments)
- Proper date range filtering to capture only the previous month's
dividend rounds
## Review & Testing Checklist for Human
- [ ] **Verify Flexile fee calculation logic** - Confirm 2.9% + 30¢
capped at $30 calculation is mathematically correct and matches business
requirements (this was updated from initial 1.5% + 50¢ capped at $15)
- [ ] **Test CSV generation with real production data** - Run the
service manually in Rails console with actual dividend rounds to verify
correct output format, calculations, and performance
- [ ] **Confirm email delivery in staging/production** - Ensure
AdminMailer.custom works correctly with CSV attachments and reaches
intended recipients (solson@earlygrowth.com, howard@antiwork.com)
- [ ] **Review database query performance** - Check that the complex
joins and filtering perform adequately with production data volumes
- [ ] **Validate monthly scheduling timing** - Verify that the 1st of
month at 4 PM UTC timing aligns with accounting workflow needs
**Recommended Test Plan:**
1. Run `DividendReportCsv.new(DividendRound.where("issued_at >= ? AND
issued_at <= ?", 1.month.ago.beginning_of_month,
1.month.ago.end_of_month)).generate` in Rails console
2. Test the scheduled job timing and email delivery in staging
environment
3. Manually verify fee calculations against a few recent dividend rounds
(should be 2.9% + 30¢, capped at $30)
4. Check query performance with production data volumes
---
### Diagram
```mermaid
%%{ init : { "theme" : "default" }}%%
graph TB
subgraph "Scheduling"
schedule["config/sidekiq_schedule.yml"]:::minor-edit
end
subgraph "Job Processing"
job["app/sidekiq/dividend_report_csv_email_job.rb"]:::major-edit
service["app/services/dividend_report_csv.rb"]:::major-edit
end
subgraph "Data Models"
dividend_round["DividendRound"]:::context
dividend["Dividend"]:::context
dividend_payment["DividendPayment"]:::context
company["Company"]:::context
end
subgraph "Email System"
admin_mailer["AdminMailer"]:::context
end
subgraph "Testing"
spec["spec/services/dividend_report_csv_spec.rb"]:::major-edit
end
schedule --> job
job --> service
service --> dividend_round
service --> dividend
service --> dividend_payment
service --> company
job --> admin_mailer
subgraph Legend
L1["Major Edit"]:::major-edit
L2["Minor Edit"]:::minor-edit
L3["Context/No Edit"]:::context
end
classDef major-edit fill:#90EE90
classDef minor-edit fill:#87CEEB
classDef context fill:#FFFFFF
```
### Notes
- **Environment limitation**: Could not fully test due to Redis
connection issues in test environment - manual testing in
production/staging is essential
- **Fee calculation updated**: Changed from 1.5% + 50¢ capped at $15 to
2.9% + 30¢ capped at $30 per user request
- **Date filtering fixed**: Addressed AI review comment to use proper
date range (beginning to end of last month) instead of just greater than
beginning
- **Email recipients updated**: Removed raul@gumroad.com and added
howard@antiwork.com per GitHub comment
- **Data scope**: Report includes only dividend rounds with successful
payments from the previous month
- **CI status**: All checks passing (6 pass, 0 fail, 2 skipping)
- **Session reference**: Link to Devin run:
https://app.devin.ai/sessions/1ccd94c85c884032bf9a7fdf50343642
- **Requested by**: sahil.lavingia@gmail.com (Sahil Lavingia)
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: sahil.lavingia@gmail.com <sahil.lavingia@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Sharang Dashputre <sharang.d@gmail.com>1 parent 099bbed commit e1bdf8b
File tree
8 files changed
+471
-3
lines changed- backend
- app
- services
- sidekiq
- config
- spec
- fixtures/vcr_cassettes/DividendReportCsvEmailJob/_perform
- services
- sidekiq
- docs
8 files changed
+471
-3
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
73 | 73 | | |
74 | 74 | | |
75 | 75 | | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
Lines changed: 59 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 113 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
0 commit comments