Repository navigation
Main - #1836
Open
tarunnjoshi wants to merge 39 commits into
Open
Main#1836tarunnjoshi wants to merge 39 commits into
tarunnjoshi wants to merge 39 commits into
Conversation
Contributions imported from CSV never reached the camp's totals and counts. The import saves each contribution as Pending and completes it with a separate Payment save; the post hooks marked the contribution as processed on the first save and skipped the one that completed it. Cancelled or refunded contributions were never subtracted either, and material contributions entered from the back end were not counted. All five fields are now recalculated from the database by one function, recalculateContributionStats(), whenever a monetary contribution or a Material Contribution activity linked to a collection source is created, edited or deleted. The previous source is refreshed too when a record is moved or deleted. Values are only saved when they change. update-contribution-count.php now uses the same function, recalculates all five fields, runs as a dry run unless APPLY=1, accepts IDS= to limit the run, writes a CSV report, and never changes collection sources whose values were typed in by hand on an outcome form. Refs coloredcow-admin/goonj-crm#392 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replaces the previous commit on this branch with a smaller fix inside the existing functions: the old hook names, handlers and update-contribution-count.php are kept as they are on dev. The CSV import saves a contribution as Pending and completes it with a separate Payment save. updateMonetaryContributionTotalAmount and updateMonetaryContributorsCount remembered a contribution as processed on its first save, so the save that completed it was skipped and the camp's Footfall & Contribution Details never included imported contributions. They also only ran for Completed contributions, so a cancellation never brought the totals down. Both hooks now remember each status of a contribution once instead of each contribution once, and run whatever the status; the totals are still summed from Completed contributions only. updateUniqueContributorsCount gets an optional flag so a contribution that is not Completed is not counted as an extra contributor. Adds cli/backfill-collection-source-contribution-stats.php to correct the affected records: dry run by default, APPLY=1 to save, IDS= to limit, CSV report, and never changes values typed in by hand on an outcome form. Refs coloredcow-admin/goonj-crm#392 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Any Completed contribution whose payment method is not Razorpay (Credit Card) or Cash/Cheque (UPI, Wire Transfer, and any method added later) now goes into the new Core_Contribution_Details.Total_Other_Monetary_Contributions field. updateMonetaryContributionTotalAmount adds it, the existing delete hook subtracts it, and the backfill script recalculates it. The custom field has to exist on an environment before this is deployed. Refs coloredcow-admin/goonj-crm#392 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
updateEventMonetaryContributionTotalAmount added a contribution's amount to the event's Online/Cash total each time the contribution was saved, so any later save of the same contribution (an edit, a receipt or settlement update) counted it again. Recalculate both totals from all Completed contributions linked to the event instead, the same fix the camp totals got in ddccbc6. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Any Completed contribution on an event whose payment method is not Razorpay (Credit Card) or Cash/Cheque (UPI, Wire Transfer, and any method added later) now goes into the new Goonj_Events_Outcome.Total_Other_Monetary_Contributions field. updateEventMonetaryContributionTotalAmount adds it and the existing delete hook subtracts it, the same as the camp totals. The custom field has to exist on an environment before this is deployed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Same fix as the camp totals. updateEventMonetaryContributionTotalAmount and updateEventMonetaryContributorsCount remembered a contribution as processed on its first save and only ran for Completed contributions, so a CSV-imported contribution (saved as Pending, then completed by a separate Payment save) was never counted, and a cancellation never brought the event's totals and counts down. Both hooks now remember each status of a contribution once instead of each contribution once, and run whatever the status; totals and counts are still calculated from Completed contributions only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Afform saves the submission record before the activity, so updateEventMatrialContributorsCount ran before the new Material Contribution activity existed and the event's unique material and total contributor counts always missed the latest donor. Count the submitting contact explicitly, the same way the camp material hook does. updateUniqueContributorsCount gets an optional $currentContactId; the monetary hook's call is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…totals Count CSV-imported and cancelled contributions in camp totals
…ents A Goonj Engagement Intent (JSM) submission that picks "Organise activities with Goonj" now creates the matching intents, so the team no longer re-enters them by hand (coloredcow-admin/goonj-crm#390). - New EngagementIntentTransferService runs after the JSM submission is saved, once per engagement intent, and never blocks the submission. - Decision rules for every Register as / Activities combination: Collection Drive folds Fundraising, Awareness Session, Upcycled Product Stall and Book Fair into the camp; Disaster Photo Exhibition and "Provide space" create their own intents; individual dropping center and Goonj Activities need a Completed induction. - Individual Collection Camp: the contact becomes a volunteer the way the camp + volunteer form does it, so the existing induction and slot email fire once; camp gets In Review, 10 AM - 1 PM on the JSM date, open to public, Other Activities, Intent Source and the JSM link. - Individual Dropping Center: created with the doc defaults, 10:00 AM to 1:00 PM timing, name and number like the check-user page fills them. - The JSM record gets "Intent Transferred" (or "...to collection camp, rest activities mentioned in Notes/Remarks") and a remark for anything skipped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Activities picked on the engagement form now create one combined Individual Goonj Activities intent for inducted volunteers (coloredcow-admin/goonj-crm#390). - Fundraising, Awareness Session, Upcycled Product Stall, Book Fair and Disaster Photo Exhibition map to the form's engagement values; Awareness Session maps to Knowing Goonj Session, the closest option. - Register as Individual, 10 AM - 1 PM on the JSM date, open to public, name and number the way the check-user page prefills them. - Every intent with a start and end now shares the 10 AM - 1 PM timing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The engagement form matches a returning person to their existing contact without updating it, so the DPDP consent they ticked was dropped. Save it on the contact when they have none yet; the consent date is then stamped by DpdpConsentService as for every other form. A contact who already gave consent keeps their original record, and nothing is saved on the intents (coloredcow-admin/goonj-crm#390). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When an institution picks Collection Drive on the engagement form, create the Institution Collection Camp intent the public institution form would create (coloredcow-admin/goonj-crm#390). - The person who filled the form is the Institution POC; the organisation is kept as the typed name, and the team picks the Organization contact on the verification form as for any public submission. - "Register as" maps to the shared institution option list by value (NGO and Foundation share the name "Foundation" on production); "Other" keeps the typed institution type. - Initiated By External, not open to public, no creative activity, India, 10 AM - 1 PM on the JSM date; folded activities go to Other Activities. - Office, coordinator and IHC/PCC come from the existing create hook. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The requirement maps the engagement form's Address to the contact's Street Address (camp + volunteer form and the three institution forms), next to the state and city already copied for chapter mapping. Write it on the contact's primary address too; a blank address never clears the street already there (coloredcow-admin/goonj-crm#390). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An address already on the contact is never replaced by the one typed on the engagement form; the form's address is only added where the contact has no street address yet (coloredcow-admin/goonj-crm#390). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When an institution picks "Provide space for material collection or storage" on the engagement form, create the Institution Dropping Center intent (coloredcow-admin/goonj-crm#390). - Same split as the institution camp: the engagement form's person is the Institution POC, the organisation stays the typed name until the team picks the Organization contact on the verification form. - Doc defaults: open to public Yes, donation box No, permission letter No, timing "10:00 AM to 1:00 PM", opening date from the engagement form, Initiated By External. - Office and coordinator come from the existing create hook. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Activities an institution picks on the engagement form now create one combined Institution Goonj Activities intent, and every Register as / Activities combination is covered (coloredcow-admin/goonj-crm#390). - Engagement values from the institution option list (Awareness Session as Knowing Goonj Session); 10 AM - 1 PM on the JSM date. - Same split as the other institution intents: the engagement form's person is the POC, the organisation stays a typed name until the team picks the Organization on the review form; "Other" keeps the typed type. - Office and coordinator come from the existing create hook. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every intent now shows where it came from (coloredcow-admin/goonj-crm#390): intents the engagement form creates already say "Engagement Form", and any intent created from another form now gets "Public Form". - Set once, when the intent's Core Details are first saved; later edits and existing intents are left as they are. - Covers the 6 public intent forms, the back-end/admin forms and API creates. - Does nothing until the Intent Source field exists, so the code can go out before the field is added on the server. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The two new Engagement Intent statuses and the Intent Source options are added by hand on staging and production (coloredcow-admin/goonj-crm#390). CiviCRM's option screen lets us type the value but not the machine name: "Intent Transferred" would be saved with the name "Intent Transferred", so a lookup by name would never match. Write them by value instead (status 8/9, source 1/2), which is what the runbook asks for on every site. Tested on local with the two statuses re-added through Administer → Option Groups: both statuses and both sources are set as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Option values can differ between sites and change when an option is deleted and added again, so the auto-transfer now finds every option it writes by its name, read off production (coloredcow-admin/goonj-crm#390): statuses, Intent Source, "An individual", the Yes / No answers, External, the Goonj Activities options (same names on the individual and institution forms) and the volunteer defaults. The two new statuses and the two Intent Source options are created by hand with these names. Exceptions: - Institution "You wish to register as" is matched by label: NGO and Foundation both carry the name "Foundation" on production, and the existing coordinator mapping relies on that name. - The institution camp's Country is a text field that keeps the country id, so the id of India is looked up by the country's name. Tested on local: individual camp + volunteer defaults, inducted dropping center + Goonj Activities, institution NGO / Foundation / Other / College and a public form give the same stored values as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Found while testing every case of the requirement end to end on local (coloredcow-admin/goonj-crm#390): - Existing contacts: the engagement form's address now only fills the parts of the contact's address that are empty. Before, the street was kept but the city and state were overwritten, which mixed two addresses (e.g. "B-7, Koregaon Park" ended up in Mumbai instead of Pune). - Saving the same submission again no longer repeats a remark such as "...was not created because the induction status is not Completed." - A failure while sending the camp initiator's induction email is logged on its own and no longer reported as "could not create the camp intent", since the camp already exists at that point. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The two new Engagement Intent statuses are added by hand through the Status field's Multiple Choice Options (Add Option) screen, which makes the name from the label and cuts it at 31 characters (coloredcow-admin/goonj-crm#390): "Intent Transferred to collection camp, rest activities mentioned in Notes/Remarks" becomes "Intent_Transferred_to_collectio". Look the status up by that name so no API Explorer step is needed. The existing production options were named the same way (e.g. Provide_space_for_material_coll). Tested on local with both choices added through that screen: the folded camp case gets status 9, the plain case status 8. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Source only has to tell the team which intents came from the engagement form (coloredcow-admin/goonj-crm#390). Those intents are already set to "Engagement Form" when the transfer creates them. Remove the hook that also wrote "Public Form" on every intent saved from the other public and admin forms: those forms are back to exactly how they were, and the intent lists show an empty Source as "Public Form" (SearchKit column, as estimated). Tested on local: public camp form → Source empty, office set as before; engagement form → institution camp with Source "Engagement Form" and the engagement intent at "Intent Transferred". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review suggestion on #1826: the activity option name "Awarness_Session" is the name stored in CiviCRM (production and staging), and the code matches options by name, so correcting the spelling would break the match. Comment only, no behaviour change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
JSM: auto-create camp, dropping center and Goonj Activities intents from the engagement form
The monetary buttons shown after a QR scan use a root-relative /contribute/ path, so they resolve against whichever host served the page. Those pages are served from the CRM domain, which kept donors on crm.goonj.org even though goonj.org/contribute/ is now proxied. Add goonj_public_url() and use it at the two monetary button call sites. It prefixes GOONJ_PUBLIC_BASE_URL when that constant is defined and returns the path untouched otherwise, so local and staging keep their current behaviour and only an environment that sets the constant sends donors to the public domain. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The renewal reminder email sent the donor to crm.goonj.org, so they landed on the CRM domain even though the same page is now served at goonj.org/contribute/website-user/. Verified both resolve to the same contribution page and the onward redirect is root-relative, so the donor now stays on goonj.org. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The donation buttons on the action pages a QR scan lands on are built from home_url(), which is the CRM domain, so the donor stayed on crm.goonj.org. These are the buttons actually rendered on those pages. Add gb_goonj_donation_base_url() and use it at the three call sites. It returns GOONJ_PUBLIC_BASE_URL when that constant is defined and falls back to home_url() otherwise, so local and staging keep their current absolute CRM links. build/render.php is updated alongside src, which is what the plugin build step copies. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The public domain serves /contribute/ only; the slash-less form falls through to the website's own 404. The CRM domain hid this because it redirects to add the slash, so the links worked there either way. Only the public-domain branch gains the slash. The home_url() fallback is left as it was, so local and staging are untouched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This reverts commit 0033400.
Send monetary buttons to the public donation domain
The public domain serves /contribute/ only and answers the slash-less form with the website's own 404. The CRM domain hid this because it redirects to add the slash, so the links worked there either way. Both branches of the helper now carry the slash, so the CRM domain also gets the canonical URL and saves a redirect. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Keep the trailing slash on the contribution URL
Making a contact a volunteer (volunteer forms, and the Engagement form's individual Collection Drive) took several seconds inside the submit: - fetchTypeOfInduction looked up the Goonj office for the city with no select, limit or contact type, so it scanned every contact and loaded their groups and tags (about 2 s per volunteer on MySQL 8). - The "induction already exists" checks filtered on target_contact_id, which scans every induction activity; they now join on the target row. Results are unchanged (checked on 450 contacts and 64 cities). Locally, individual to volunteer goes from 4.4 s to 0.8 s and an Engagement form individual Collection Drive submission from 6.1 s to 2.2 s. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Speed up the induction checks run for every new volunteer
The "View Directions on Google Maps" link in the urban visit emails to the external POC (on authorisation and the day-of reminder) put the office address into the URL as-is. The Bangalore address has "25&26", so the & cut the search to "GOONJ, Survey No. 25" and Maps listed every Goonj location. Mumbai worked because its address has no &. - Encode the address before building the Maps link. - Read the office's primary address. Bangalore and Dhalwala Rishikesh also have an old address, and the email could pick that one. Also ran phpcbf --standard=Drupal on the file (whitespace, doc comments, an unused import). Refs coloredcow-admin/goonj-crm#170 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keep the full office address in the visit directions link
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The client asked (19 Oct 2026) that intents created from the engagement form answer the permission letter question with No: - Individual Collection Camp: "Do you require permission letters from Goonj to get permission from authorities for organizing camps?" - Individual Dropping Center: "Some volunteers require permission letters from Goonj to get permission from authorities for Dropping Center. Do you need one too?" Both fields and their Yes/No options are the same on local, staging and production. They are set by option name, as the institution dropping center already does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
JSM: answer the permission letter questions with No
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.