+
+
+
+
+
+`;
+
+exports[`Modal nothing displayed if inactive 1`] = `""`;
diff --git a/javascripts/src/components/common/__snapshots__/ProgressableButton.spec.tsx.snap b/app/javascript/legacy_react/src/components/common/__snapshots__/ProgressableButton.spec.tsx.snap
similarity index 100%
rename from javascripts/src/components/common/__snapshots__/ProgressableButton.spec.tsx.snap
rename to app/javascript/legacy_react/src/components/common/__snapshots__/ProgressableButton.spec.tsx.snap
diff --git a/javascripts/src/components/common/__snapshots__/ScreenReaderOnlyText.spec.tsx.snap b/app/javascript/legacy_react/src/components/common/__snapshots__/ScreenReaderOnlyText.spec.tsx.snap
similarity index 100%
rename from javascripts/src/components/common/__snapshots__/ScreenReaderOnlyText.spec.tsx.snap
rename to app/javascript/legacy_react/src/components/common/__snapshots__/ScreenReaderOnlyText.spec.tsx.snap
diff --git a/app/javascript/legacy_react/src/components/common/__snapshots__/Spinner.spec.tsx.snap b/app/javascript/legacy_react/src/components/common/__snapshots__/Spinner.spec.tsx.snap
new file mode 100644
index 00000000..9014bd65
--- /dev/null
+++ b/app/javascript/legacy_react/src/components/common/__snapshots__/Spinner.spec.tsx.snap
@@ -0,0 +1,165 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Spinner has custom color 1`] = `
+
+
+
+
+ Loading...
+
+
+
+
+`;
+
+exports[`Spinner is large 1`] = `
+
+
+
+
+ Loading...
+
+
+
+
+`;
+
+exports[`Spinner is normal 1`] = `
+
+
+
+
+ Loading...
+
+
+
+
+`;
+
+exports[`Spinner is small 1`] = `
+
+
+
+
+ Loading...
+
+
+
+
+`;
diff --git a/javascripts/src/components/common/__snapshots__/StandardFieldComponent.spec.tsx.snap b/app/javascript/legacy_react/src/components/common/__snapshots__/StandardFieldComponent.spec.tsx.snap
similarity index 100%
rename from javascripts/src/components/common/__snapshots__/StandardFieldComponent.spec.tsx.snap
rename to app/javascript/legacy_react/src/components/common/__snapshots__/StandardFieldComponent.spec.tsx.snap
diff --git a/javascripts/src/components/common/__snapshots__/layout.spec.tsx.snap b/app/javascript/legacy_react/src/components/common/__snapshots__/layout.spec.tsx.snap
similarity index 100%
rename from javascripts/src/components/common/__snapshots__/layout.spec.tsx.snap
rename to app/javascript/legacy_react/src/components/common/__snapshots__/layout.spec.tsx.snap
diff --git a/javascripts/src/components/common/fields.tsx b/app/javascript/legacy_react/src/components/common/fields.tsx
similarity index 98%
rename from javascripts/src/components/common/fields.tsx
rename to app/javascript/legacy_react/src/components/common/fields.tsx
index fa8be668..fe151380 100644
--- a/javascripts/src/components/common/fields.tsx
+++ b/app/javascript/legacy_react/src/components/common/fields.tsx
@@ -1,7 +1,7 @@
// License: LGPL-3.0-or-later
import * as React from 'react';
import { observer } from "mobx-react";
-import { Field } from "../../../../types/mobx-react-form";
+import { Field } from "../../../../../../types/mobx-react-form";
import LabeledFieldComponent from "./LabeledFieldComponent";
import { HoudiniField } from "../../lib/houdini_form";
import ReactInput from "./form/ReactInput";
diff --git a/javascripts/src/components/common/form/ReactForm.tsx b/app/javascript/legacy_react/src/components/common/form/ReactForm.tsx
similarity index 100%
rename from javascripts/src/components/common/form/ReactForm.tsx
rename to app/javascript/legacy_react/src/components/common/form/ReactForm.tsx
diff --git a/javascripts/src/components/common/form/ReactInput.spec.tsx b/app/javascript/legacy_react/src/components/common/form/ReactInput.spec.tsx
similarity index 100%
rename from javascripts/src/components/common/form/ReactInput.spec.tsx
rename to app/javascript/legacy_react/src/components/common/form/ReactInput.spec.tsx
diff --git a/javascripts/src/components/common/form/ReactInput.tsx b/app/javascript/legacy_react/src/components/common/form/ReactInput.tsx
similarity index 100%
rename from javascripts/src/components/common/form/ReactInput.tsx
rename to app/javascript/legacy_react/src/components/common/form/ReactInput.tsx
diff --git a/javascripts/src/components/common/form/ReactMaskedInput.tsx b/app/javascript/legacy_react/src/components/common/form/ReactMaskedInput.tsx
similarity index 100%
rename from javascripts/src/components/common/form/ReactMaskedInput.tsx
rename to app/javascript/legacy_react/src/components/common/form/ReactMaskedInput.tsx
diff --git a/javascripts/src/components/common/form/ReactSelect.spec.tsx b/app/javascript/legacy_react/src/components/common/form/ReactSelect.spec.tsx
similarity index 100%
rename from javascripts/src/components/common/form/ReactSelect.spec.tsx
rename to app/javascript/legacy_react/src/components/common/form/ReactSelect.spec.tsx
diff --git a/javascripts/src/components/common/form/ReactSelect.tsx b/app/javascript/legacy_react/src/components/common/form/ReactSelect.tsx
similarity index 96%
rename from javascripts/src/components/common/form/ReactSelect.tsx
rename to app/javascript/legacy_react/src/components/common/form/ReactSelect.tsx
index acba6f6e..c3e0bb42 100644
--- a/javascripts/src/components/common/form/ReactSelect.tsx
+++ b/app/javascript/legacy_react/src/components/common/form/ReactSelect.tsx
@@ -2,7 +2,7 @@
import * as React from 'react';
import { observer } from 'mobx-react';
import {InjectedIntlProps, injectIntl} from 'react-intl';
-import {Field} from "../../../../../types/mobx-react-form";
+import {Field} from "../../../../../../../types/mobx-react-form";
import {InputHTMLAttributes} from "react";
import {action, observable} from "mobx";
import {SelectHTMLAttributes} from "react";
diff --git a/javascripts/src/components/common/form/ReactTextarea.spec.tsx b/app/javascript/legacy_react/src/components/common/form/ReactTextarea.spec.tsx
similarity index 100%
rename from javascripts/src/components/common/form/ReactTextarea.spec.tsx
rename to app/javascript/legacy_react/src/components/common/form/ReactTextarea.spec.tsx
diff --git a/javascripts/src/components/common/form/ReactTextarea.tsx b/app/javascript/legacy_react/src/components/common/form/ReactTextarea.tsx
similarity index 95%
rename from javascripts/src/components/common/form/ReactTextarea.tsx
rename to app/javascript/legacy_react/src/components/common/form/ReactTextarea.tsx
index a948a2af..3e8a826a 100644
--- a/javascripts/src/components/common/form/ReactTextarea.tsx
+++ b/app/javascript/legacy_react/src/components/common/form/ReactTextarea.tsx
@@ -2,7 +2,7 @@
import * as React from 'react';
import { observer } from 'mobx-react';
import {InjectedIntlProps, injectIntl} from 'react-intl';
-import {Field} from "../../../../../types/mobx-react-form";
+import {Field} from "../../../../../../../types/mobx-react-form";
import {InputHTMLAttributes, ReactText, TextareaHTMLAttributes} from "react";
import {action, observable} from "mobx";
import {ReactInputProps} from "./react_input_props";
diff --git a/javascripts/src/components/common/form/__snapshots__/ReactInput.spec.tsx.snap b/app/javascript/legacy_react/src/components/common/form/__snapshots__/ReactInput.spec.tsx.snap
similarity index 100%
rename from javascripts/src/components/common/form/__snapshots__/ReactInput.spec.tsx.snap
rename to app/javascript/legacy_react/src/components/common/form/__snapshots__/ReactInput.spec.tsx.snap
diff --git a/javascripts/src/components/common/form/__snapshots__/ReactSelect.spec.tsx.snap b/app/javascript/legacy_react/src/components/common/form/__snapshots__/ReactSelect.spec.tsx.snap
similarity index 100%
rename from javascripts/src/components/common/form/__snapshots__/ReactSelect.spec.tsx.snap
rename to app/javascript/legacy_react/src/components/common/form/__snapshots__/ReactSelect.spec.tsx.snap
diff --git a/javascripts/src/components/common/form/__snapshots__/ReactTextarea.spec.tsx.snap b/app/javascript/legacy_react/src/components/common/form/__snapshots__/ReactTextarea.spec.tsx.snap
similarity index 100%
rename from javascripts/src/components/common/form/__snapshots__/ReactTextarea.spec.tsx.snap
rename to app/javascript/legacy_react/src/components/common/form/__snapshots__/ReactTextarea.spec.tsx.snap
diff --git a/javascripts/src/components/common/form/react_input_props.ts b/app/javascript/legacy_react/src/components/common/form/react_input_props.ts
similarity index 100%
rename from javascripts/src/components/common/form/react_input_props.ts
rename to app/javascript/legacy_react/src/components/common/form/react_input_props.ts
diff --git a/javascripts/src/components/common/layout.spec.tsx b/app/javascript/legacy_react/src/components/common/layout.spec.tsx
similarity index 100%
rename from javascripts/src/components/common/layout.spec.tsx
rename to app/javascript/legacy_react/src/components/common/layout.spec.tsx
diff --git a/javascripts/src/components/common/layout.tsx b/app/javascript/legacy_react/src/components/common/layout.tsx
similarity index 100%
rename from javascripts/src/components/common/layout.tsx
rename to app/javascript/legacy_react/src/components/common/layout.tsx
diff --git a/javascripts/src/components/common/selectable_table_row/SelectableTableRow.spec.tsx b/app/javascript/legacy_react/src/components/common/selectable_table_row/SelectableTableRow.spec.tsx
similarity index 100%
rename from javascripts/src/components/common/selectable_table_row/SelectableTableRow.spec.tsx
rename to app/javascript/legacy_react/src/components/common/selectable_table_row/SelectableTableRow.spec.tsx
diff --git a/javascripts/src/components/common/selectable_table_row/SelectableTableRow.tsx b/app/javascript/legacy_react/src/components/common/selectable_table_row/SelectableTableRow.tsx
similarity index 100%
rename from javascripts/src/components/common/selectable_table_row/SelectableTableRow.tsx
rename to app/javascript/legacy_react/src/components/common/selectable_table_row/SelectableTableRow.tsx
diff --git a/javascripts/src/components/common/selectable_table_row/connect.tsx b/app/javascript/legacy_react/src/components/common/selectable_table_row/connect.tsx
similarity index 100%
rename from javascripts/src/components/common/selectable_table_row/connect.tsx
rename to app/javascript/legacy_react/src/components/common/selectable_table_row/connect.tsx
diff --git a/javascripts/src/components/common/svg/CloseButton.tsx b/app/javascript/legacy_react/src/components/common/svg/CloseButton.tsx
similarity index 96%
rename from javascripts/src/components/common/svg/CloseButton.tsx
rename to app/javascript/legacy_react/src/components/common/svg/CloseButton.tsx
index d8e23f00..5167c93c 100644
--- a/javascripts/src/components/common/svg/CloseButton.tsx
+++ b/app/javascript/legacy_react/src/components/common/svg/CloseButton.tsx
@@ -1,5 +1,5 @@
// License: LGPL-3.0-or-later
-import React = require("react");
+import * as React from "react";
interface CloseButtonProps {
backgroundCircleStyle:React.CSSProperties
foregroundCircleStyle:React.CSSProperties
diff --git a/javascripts/src/components/common/svg/checkbox.tsx b/app/javascript/legacy_react/src/components/common/svg/checkbox.tsx
similarity index 100%
rename from javascripts/src/components/common/svg/checkbox.tsx
rename to app/javascript/legacy_react/src/components/common/svg/checkbox.tsx
diff --git a/javascripts/src/components/common/test/react_test_helpers.tsx b/app/javascript/legacy_react/src/components/common/test/react_test_helpers.tsx
similarity index 97%
rename from javascripts/src/components/common/test/react_test_helpers.tsx
rename to app/javascript/legacy_react/src/components/common/test/react_test_helpers.tsx
index ad6ab99b..888f01e7 100644
--- a/javascripts/src/components/common/test/react_test_helpers.tsx
+++ b/app/javascript/legacy_react/src/components/common/test/react_test_helpers.tsx
@@ -33,7 +33,7 @@ export function mountForMobx(props:TProps,
return mount()
+ __childrenCreator={rootComponentCreator as any} />)
}
/**
@@ -45,7 +45,7 @@ export function mountForMobx(props:TProps,
export function mountForMobxWithIntl(props:TProps,
rootComponentCreator:(props:TProps) => React.ReactNode): ReactWrapper {
return mountWithIntl()
+ __childrenCreator={rootComponentCreator as any} />)
}
diff --git a/javascripts/src/components/common/test/unique_id_mock.ts b/app/javascript/legacy_react/src/components/common/test/unique_id_mock.ts
similarity index 100%
rename from javascripts/src/components/common/test/unique_id_mock.ts
rename to app/javascript/legacy_react/src/components/common/test/unique_id_mock.ts
diff --git a/javascripts/src/components/common/wizard/RAT/Tab.ts b/app/javascript/legacy_react/src/components/common/wizard/RAT/Tab.ts
similarity index 100%
rename from javascripts/src/components/common/wizard/RAT/Tab.ts
rename to app/javascript/legacy_react/src/components/common/wizard/RAT/Tab.ts
diff --git a/javascripts/src/components/common/wizard/RAT/TabList.ts b/app/javascript/legacy_react/src/components/common/wizard/RAT/TabList.ts
similarity index 100%
rename from javascripts/src/components/common/wizard/RAT/TabList.ts
rename to app/javascript/legacy_react/src/components/common/wizard/RAT/TabList.ts
diff --git a/javascripts/src/components/common/wizard/RAT/TabPanel.ts b/app/javascript/legacy_react/src/components/common/wizard/RAT/TabPanel.ts
similarity index 100%
rename from javascripts/src/components/common/wizard/RAT/TabPanel.ts
rename to app/javascript/legacy_react/src/components/common/wizard/RAT/TabPanel.ts
diff --git a/javascripts/src/components/common/wizard/RAT/Wrapper.spec.tsx b/app/javascript/legacy_react/src/components/common/wizard/RAT/Wrapper.spec.tsx
similarity index 100%
rename from javascripts/src/components/common/wizard/RAT/Wrapper.spec.tsx
rename to app/javascript/legacy_react/src/components/common/wizard/RAT/Wrapper.spec.tsx
diff --git a/javascripts/src/components/common/wizard/RAT/Wrapper.ts b/app/javascript/legacy_react/src/components/common/wizard/RAT/Wrapper.ts
similarity index 96%
rename from javascripts/src/components/common/wizard/RAT/Wrapper.ts
rename to app/javascript/legacy_react/src/components/common/wizard/RAT/Wrapper.ts
index 54f0f9d8..66f1e3d5 100644
--- a/javascripts/src/components/common/wizard/RAT/Wrapper.ts
+++ b/app/javascript/legacy_react/src/components/common/wizard/RAT/Wrapper.ts
@@ -5,7 +5,7 @@ import {TabManagerParent} from "./abstract_tabcomponent_state";
import {observer} from 'mobx-react';
import specialAssign from "./specialAssign";
-import PropTypes = require('prop-types');
+const PropTypes = require ('prop-types');
interface WrapperProps {
manager: TabManagerParent
diff --git a/javascripts/src/components/common/wizard/RAT/__snapshots__/Wrapper.spec.tsx.snap b/app/javascript/legacy_react/src/components/common/wizard/RAT/__snapshots__/Wrapper.spec.tsx.snap
similarity index 100%
rename from javascripts/src/components/common/wizard/RAT/__snapshots__/Wrapper.spec.tsx.snap
rename to app/javascript/legacy_react/src/components/common/wizard/RAT/__snapshots__/Wrapper.spec.tsx.snap
diff --git a/javascripts/src/components/common/wizard/RAT/abstract_tabcomponent_state.spec.tsx b/app/javascript/legacy_react/src/components/common/wizard/RAT/abstract_tabcomponent_state.spec.tsx
similarity index 100%
rename from javascripts/src/components/common/wizard/RAT/abstract_tabcomponent_state.spec.tsx
rename to app/javascript/legacy_react/src/components/common/wizard/RAT/abstract_tabcomponent_state.spec.tsx
diff --git a/javascripts/src/components/common/wizard/RAT/abstract_tabcomponent_state.ts b/app/javascript/legacy_react/src/components/common/wizard/RAT/abstract_tabcomponent_state.ts
similarity index 99%
rename from javascripts/src/components/common/wizard/RAT/abstract_tabcomponent_state.ts
rename to app/javascript/legacy_react/src/components/common/wizard/RAT/abstract_tabcomponent_state.ts
index d55d3b89..c3c6cd3d 100644
--- a/javascripts/src/components/common/wizard/RAT/abstract_tabcomponent_state.ts
+++ b/app/javascript/legacy_react/src/components/common/wizard/RAT/abstract_tabcomponent_state.ts
@@ -1,6 +1,6 @@
// License: LGPL-3.0-or-later
import {action, computed, observable, reaction, runInAction} from "mobx";
-import _ = require("lodash");
+import * as _ from "lodash";
const createFocusGroup = require('focus-group');
diff --git a/javascripts/src/components/common/wizard/RAT/specialAssign.ts b/app/javascript/legacy_react/src/components/common/wizard/RAT/specialAssign.ts
similarity index 100%
rename from javascripts/src/components/common/wizard/RAT/specialAssign.ts
rename to app/javascript/legacy_react/src/components/common/wizard/RAT/specialAssign.ts
diff --git a/javascripts/src/components/common/wizard/Wizard.spec.tsx b/app/javascript/legacy_react/src/components/common/wizard/Wizard.spec.tsx
similarity index 100%
rename from javascripts/src/components/common/wizard/Wizard.spec.tsx
rename to app/javascript/legacy_react/src/components/common/wizard/Wizard.spec.tsx
diff --git a/javascripts/src/components/common/wizard/Wizard.tsx b/app/javascript/legacy_react/src/components/common/wizard/Wizard.tsx
similarity index 100%
rename from javascripts/src/components/common/wizard/Wizard.tsx
rename to app/javascript/legacy_react/src/components/common/wizard/Wizard.tsx
diff --git a/javascripts/src/components/common/wizard/WizardPanel.spec.tsx b/app/javascript/legacy_react/src/components/common/wizard/WizardPanel.spec.tsx
similarity index 100%
rename from javascripts/src/components/common/wizard/WizardPanel.spec.tsx
rename to app/javascript/legacy_react/src/components/common/wizard/WizardPanel.spec.tsx
diff --git a/javascripts/src/components/common/wizard/WizardPanel.tsx b/app/javascript/legacy_react/src/components/common/wizard/WizardPanel.tsx
similarity index 100%
rename from javascripts/src/components/common/wizard/WizardPanel.tsx
rename to app/javascript/legacy_react/src/components/common/wizard/WizardPanel.tsx
diff --git a/javascripts/src/components/common/wizard/WizardTab.spec.tsx b/app/javascript/legacy_react/src/components/common/wizard/WizardTab.spec.tsx
similarity index 100%
rename from javascripts/src/components/common/wizard/WizardTab.spec.tsx
rename to app/javascript/legacy_react/src/components/common/wizard/WizardTab.spec.tsx
diff --git a/javascripts/src/components/common/wizard/WizardTab.tsx b/app/javascript/legacy_react/src/components/common/wizard/WizardTab.tsx
similarity index 100%
rename from javascripts/src/components/common/wizard/WizardTab.tsx
rename to app/javascript/legacy_react/src/components/common/wizard/WizardTab.tsx
diff --git a/javascripts/src/components/common/wizard/WizardTabList.tsx b/app/javascript/legacy_react/src/components/common/wizard/WizardTabList.tsx
similarity index 100%
rename from javascripts/src/components/common/wizard/WizardTabList.tsx
rename to app/javascript/legacy_react/src/components/common/wizard/WizardTabList.tsx
diff --git a/javascripts/src/components/common/wizard/__snapshots__/Wizard.spec.tsx.snap b/app/javascript/legacy_react/src/components/common/wizard/__snapshots__/Wizard.spec.tsx.snap
similarity index 95%
rename from javascripts/src/components/common/wizard/__snapshots__/Wizard.spec.tsx.snap
rename to app/javascript/legacy_react/src/components/common/wizard/__snapshots__/Wizard.spec.tsx.snap
index 9112ff40..5e7aaba8 100644
--- a/javascripts/src/components/common/wizard/__snapshots__/Wizard.spec.tsx.snap
+++ b/app/javascript/legacy_react/src/components/common/wizard/__snapshots__/Wizard.spec.tsx.snap
@@ -43,21 +43,21 @@ exports[`Wizard Move back on disabled make first invalid so move back there 1`]
-
+
-
+
-
+
@@ -112,21 +112,21 @@ exports[`Wizard Move back on disabled make first invalid so move back there 2`]
-
+
-
+
-
+
@@ -181,21 +181,21 @@ exports[`Wizard Move back on disabled make second invalid so move back there 1`]
-
+
-
+
-
+
@@ -250,21 +250,21 @@ exports[`Wizard first tab is active 1`] = `
-
+
-
+
-
+
@@ -319,21 +319,21 @@ exports[`Wizard go to the second tab go to next via backend 1`] = `
-
+
-
+
-
+
@@ -388,21 +388,21 @@ exports[`Wizard go to the second tab set via next click 1`] = `
-
+
-
+
-
+
@@ -457,21 +457,21 @@ exports[`Wizard go to the second tab set via tab click 1`] = `
-
+
-
+
-
+
diff --git a/javascripts/src/components/common/wizard/__snapshots__/WizardPanel.spec.tsx.snap b/app/javascript/legacy_react/src/components/common/wizard/__snapshots__/WizardPanel.spec.tsx.snap
similarity index 100%
rename from javascripts/src/components/common/wizard/__snapshots__/WizardPanel.spec.tsx.snap
rename to app/javascript/legacy_react/src/components/common/wizard/__snapshots__/WizardPanel.spec.tsx.snap
diff --git a/javascripts/src/components/common/wizard/abstract_wizard_state.spec.tsx b/app/javascript/legacy_react/src/components/common/wizard/abstract_wizard_state.spec.tsx
similarity index 100%
rename from javascripts/src/components/common/wizard/abstract_wizard_state.spec.tsx
rename to app/javascript/legacy_react/src/components/common/wizard/abstract_wizard_state.spec.tsx
diff --git a/javascripts/src/components/common/wizard/abstract_wizard_state.ts b/app/javascript/legacy_react/src/components/common/wizard/abstract_wizard_state.ts
similarity index 98%
rename from javascripts/src/components/common/wizard/abstract_wizard_state.ts
rename to app/javascript/legacy_react/src/components/common/wizard/abstract_wizard_state.ts
index a6ab3c78..ab5a05f4 100644
--- a/javascripts/src/components/common/wizard/abstract_wizard_state.ts
+++ b/app/javascript/legacy_react/src/components/common/wizard/abstract_wizard_state.ts
@@ -1,7 +1,7 @@
// License: LGPL-3.0-or-later
import {computed, reaction} from "mobx";
import {AbstractTabComponentState, AbstractTabPanelState} from "./RAT/abstract_tabcomponent_state";
-import _ = require("lodash");
+import * as _ from "lodash";
export abstract class AbstractWizardState
extends AbstractTabComponentState {
diff --git a/javascripts/src/components/common/wizard/wizard_state.spec.ts b/app/javascript/legacy_react/src/components/common/wizard/wizard_state.spec.ts
similarity index 100%
rename from javascripts/src/components/common/wizard/wizard_state.spec.ts
rename to app/javascript/legacy_react/src/components/common/wizard/wizard_state.spec.ts
diff --git a/javascripts/src/components/common/wizard/wizard_state.ts b/app/javascript/legacy_react/src/components/common/wizard/wizard_state.ts
similarity index 99%
rename from javascripts/src/components/common/wizard/wizard_state.ts
rename to app/javascript/legacy_react/src/components/common/wizard/wizard_state.ts
index 843baa39..5b6b383f 100644
--- a/javascripts/src/components/common/wizard/wizard_state.ts
+++ b/app/javascript/legacy_react/src/components/common/wizard/wizard_state.ts
@@ -1,7 +1,7 @@
// License: LGPL-3.0-or-later
import {observable, action, computed, toJS, reaction, runInAction} from "mobx";
import {Field, Form, FieldDefinition, FieldHandlers, FieldHooks} from "mobx-react-form";
-import _ = require("lodash");
+import * as _ from "lodash";
import {AbstractWizardState, AbstractWizardTabPanelState} from "./abstract_wizard_state";
interface SubFormDefinition {
diff --git a/javascripts/src/components/create_offsite_payment_pane/CreateOffsitePaymentPane.tsx b/app/javascript/legacy_react/src/components/create_offsite_payment_pane/CreateOffsitePaymentPane.tsx
similarity index 97%
rename from javascripts/src/components/create_offsite_payment_pane/CreateOffsitePaymentPane.tsx
rename to app/javascript/legacy_react/src/components/create_offsite_payment_pane/CreateOffsitePaymentPane.tsx
index b31b2b14..751bbbbd 100644
--- a/javascripts/src/components/create_offsite_payment_pane/CreateOffsitePaymentPane.tsx
+++ b/app/javascript/legacy_react/src/components/create_offsite_payment_pane/CreateOffsitePaymentPane.tsx
@@ -3,13 +3,13 @@ import * as React from 'react';
import { observer } from 'mobx-react';
import {InjectedIntlProps, injectIntl} from 'react-intl';
import Modal from "../common/Modal";
-import { FundraiserInfo} from "../edit_payment_pane/EditPaymentPane";
+//import { FundraiserInfo} from "../edit_payment_pane/EditPaymentPane";
import {HoudiniForm} from "../../lib/houdini_form";
import {BasicField, CurrencyField, SelectField, TextareaField} from "../common/fields";
import ProgressableButton from "../common/ProgressableButton";
import {action, computed} from "mobx";
import {NonprofitTimezonedDates} from "../../lib/date";
-import {Field, FieldDefinition} from "../../../../types/mobx-react-form";
+import {Field, FieldDefinition} from "../../../../../../types/mobx-react-form";
import {createFieldDefinition} from "../../lib/mobx_utils";
import {centsToDollars, dollarsToCents} from "../../lib/format";
import {Validations} from "../../lib/vjf_rules";
@@ -18,9 +18,9 @@ import {ApiManager} from "../../lib/api_manager";
import * as CustomAPIS from "../../lib/apis";
import {CSRFInterceptor} from "../../lib/csrf_interceptor";
import {CreateOffsiteDonation, CreateOffsiteDonationModel} from "../../lib/api/create_offsite_donation";
-import blacklist = require("validator/lib/blacklist");
-import * as _ from 'lodash'
-import moment = require('moment');
+import blacklist from "validator/lib/blacklist";
+import * as _ from 'lodash';
+import moment from 'moment';
import { castToUndefinedIfBlank } from '../../lib/utils';
import ReactInput from "../common/form/ReactInput";
diff --git a/javascripts/src/components/edit_payment_pane/EditPaymentPane.tsx b/app/javascript/legacy_react/src/components/edit_payment_pane/EditPaymentPane.tsx
similarity index 99%
rename from javascripts/src/components/edit_payment_pane/EditPaymentPane.tsx
rename to app/javascript/legacy_react/src/components/edit_payment_pane/EditPaymentPane.tsx
index 6b54a46b..ce9d0260 100644
--- a/javascripts/src/components/edit_payment_pane/EditPaymentPane.tsx
+++ b/app/javascript/legacy_react/src/components/edit_payment_pane/EditPaymentPane.tsx
@@ -15,9 +15,9 @@ import {CSRFInterceptor} from "../../lib/csrf_interceptor";
import {BasicField, CurrencyField, SelectField, TextareaField} from '../common/fields';
import {TwoColumnFields} from "../common/layout";
import {Validations} from "../../lib/vjf_rules";
-import _ = require("lodash");
+import * as _ from 'lodash'
import {Dedication, parseDedication, serializeDedication} from '../../lib/dedication';
-import blacklist = require("validator/lib/blacklist");
+import blacklist from "validator/lib/blacklist";
import {createFieldDefinition} from "../../lib/mobx_utils";
import Modal from "../common/Modal";
import ReactInput from "../common/form/ReactInput";
diff --git a/javascripts/src/components/registration_page/NonprofitInfoForm.spec.tsx b/app/javascript/legacy_react/src/components/registration_page/NonprofitInfoForm.spec.tsx
similarity index 100%
rename from javascripts/src/components/registration_page/NonprofitInfoForm.spec.tsx
rename to app/javascript/legacy_react/src/components/registration_page/NonprofitInfoForm.spec.tsx
diff --git a/javascripts/src/components/registration_page/NonprofitInfoForm.tsx b/app/javascript/legacy_react/src/components/registration_page/NonprofitInfoForm.tsx
similarity index 98%
rename from javascripts/src/components/registration_page/NonprofitInfoForm.tsx
rename to app/javascript/legacy_react/src/components/registration_page/NonprofitInfoForm.tsx
index b82bc1bc..51dc4914 100644
--- a/javascripts/src/components/registration_page/NonprofitInfoForm.tsx
+++ b/app/javascript/legacy_react/src/components/registration_page/NonprofitInfoForm.tsx
@@ -2,7 +2,7 @@
import * as React from 'react';
import { observer } from 'mobx-react';
import {InjectedIntlProps, injectIntl} from 'react-intl';
-import {Field, FieldDefinition} from "../../../../types/mobx-react-form";
+import {Field, FieldDefinition} from "../../../../../../types/mobx-react-form";
import {BasicField} from "../common/fields";
import {ThreeColumnFields, TwoColumnFields} from "../common/layout";
import {Validations} from "../../lib/vjf_rules";
diff --git a/javascripts/src/components/registration_page/NonprofitInfoPanel.spec.tsx b/app/javascript/legacy_react/src/components/registration_page/NonprofitInfoPanel.spec.tsx
similarity index 100%
rename from javascripts/src/components/registration_page/NonprofitInfoPanel.spec.tsx
rename to app/javascript/legacy_react/src/components/registration_page/NonprofitInfoPanel.spec.tsx
diff --git a/javascripts/src/components/registration_page/NonprofitInfoPanel.tsx b/app/javascript/legacy_react/src/components/registration_page/NonprofitInfoPanel.tsx
similarity index 100%
rename from javascripts/src/components/registration_page/NonprofitInfoPanel.tsx
rename to app/javascript/legacy_react/src/components/registration_page/NonprofitInfoPanel.tsx
diff --git a/javascripts/src/components/registration_page/RegistrationPage.tsx b/app/javascript/legacy_react/src/components/registration_page/RegistrationPage.tsx
similarity index 100%
rename from javascripts/src/components/registration_page/RegistrationPage.tsx
rename to app/javascript/legacy_react/src/components/registration_page/RegistrationPage.tsx
diff --git a/javascripts/src/components/registration_page/RegistrationWizard.tsx b/app/javascript/legacy_react/src/components/registration_page/RegistrationWizard.tsx
similarity index 84%
rename from javascripts/src/components/registration_page/RegistrationWizard.tsx
rename to app/javascript/legacy_react/src/components/registration_page/RegistrationWizard.tsx
index 6abd2223..2303da37 100644
--- a/javascripts/src/components/registration_page/RegistrationWizard.tsx
+++ b/app/javascript/legacy_react/src/components/registration_page/RegistrationWizard.tsx
@@ -12,12 +12,15 @@ import {WizardState, WizardTabPanelState} from "../common/wizard/wizard_state";
import UserInfoPanel, * as UserInfo from "./UserInfoPanel";
import {
Nonprofit,
- NonprofitApi,
+ NonprofitsApi,
PostNonprofit,
- ValidationErrorsException
+ ValidationErrorsException,
+ UsersApi,
+ PostUser,
+ PostNonprofitUser
} from "../../../api";
-import {initializationDefinition} from "../../../../types/mobx-react-form";
+import {initializationDefinition} from "../../../../../../types/mobx-react-form";
import {ApiManager} from "../../lib/api_manager";
import {HoudiniForm, StaticFormToErrorAndBackConverter} from "../../lib/houdini_form";
import {WebUserSignInOut} from "../../lib/api/sign_in";
@@ -36,16 +39,22 @@ const setTourCookies = (nonprofit:Nonprofit) => {
document.cookie = `tour_supporters=${nonprofit.id};path=/`
document.cookie = `tour_subscribers=${nonprofit.id};path=/`
}
+/** this is just here to allow compilation. */
+interface TemporaryHackyInterface {
+ nonprofit: PostNonprofit
+ user: PostNonprofitUser
+}
export class RegistrationPageForm extends HoudiniForm {
- converter: StaticFormToErrorAndBackConverter
+ converter: StaticFormToErrorAndBackConverter
constructor(definition: initializationDefinition, options?: any) {
super(definition, options)
- this.converter = new StaticFormToErrorAndBackConverter(this.inputToForm)
+ this.converter = new StaticFormToErrorAndBackConverter(this.inputToForm)
}
- nonprofitApi: NonprofitApi
+ nonprofitApi: NonprofitsApi
+ usersApi: UsersApi
signinApi: WebUserSignInOut
options() {
@@ -78,9 +87,11 @@ export class RegistrationPageForm extends HoudiniForm {
try {
- let r = await this.nonprofitApi.postNonprofit(input)
+ const userMessage = {user: input.user}
+ let user = await this.usersApi.postUser(userMessage)
+ this.signinApi.postLogin({email: input.user.email, password: input.user.password})
+ let r = await this.nonprofitApi.postNonprofit(input.nonprofit)
setTourCookies(r)
- await this.signinApi.postLogin({email: input.user.email, password: input.user.password})
window.location.href = `/nonprofits/${r.id}/dashboard`
}
@@ -155,8 +166,9 @@ export class InnerRegistrationWizard extends React.Component {
- this.form.nonprofitApi = this.props.ApiManager.get(NonprofitApi)
+ this.form.nonprofitApi = this.props.ApiManager.get(NonprofitsApi)
this.form.signinApi = this.props.ApiManager.get(WebUserSignInOut)
+ this.form.usersApi = this.props.ApiManager.get(UsersApi)
})
}
diff --git a/javascripts/src/components/registration_page/UserInfoForm.tsx b/app/javascript/legacy_react/src/components/registration_page/UserInfoForm.tsx
similarity index 100%
rename from javascripts/src/components/registration_page/UserInfoForm.tsx
rename to app/javascript/legacy_react/src/components/registration_page/UserInfoForm.tsx
diff --git a/javascripts/src/components/registration_page/UserInfoPanel.spec.tsx b/app/javascript/legacy_react/src/components/registration_page/UserInfoPanel.spec.tsx
similarity index 100%
rename from javascripts/src/components/registration_page/UserInfoPanel.spec.tsx
rename to app/javascript/legacy_react/src/components/registration_page/UserInfoPanel.spec.tsx
diff --git a/javascripts/src/components/registration_page/UserInfoPanel.tsx b/app/javascript/legacy_react/src/components/registration_page/UserInfoPanel.tsx
similarity index 100%
rename from javascripts/src/components/registration_page/UserInfoPanel.tsx
rename to app/javascript/legacy_react/src/components/registration_page/UserInfoPanel.tsx
diff --git a/javascripts/src/components/session_login_page/SessionLoginForm.tsx b/app/javascript/legacy_react/src/components/session_login_page/SessionLoginForm.tsx
similarity index 98%
rename from javascripts/src/components/session_login_page/SessionLoginForm.tsx
rename to app/javascript/legacy_react/src/components/session_login_page/SessionLoginForm.tsx
index 3d7d3ca8..d098a8ce 100644
--- a/javascripts/src/components/session_login_page/SessionLoginForm.tsx
+++ b/app/javascript/legacy_react/src/components/session_login_page/SessionLoginForm.tsx
@@ -2,7 +2,7 @@
import * as React from 'react';
import { observer, inject} from 'mobx-react';
import {InjectedIntlProps, injectIntl, FormattedMessage} from 'react-intl';
-import {Field, FieldDefinition, Form, initializationDefinition} from "../../../../types/mobx-react-form";
+import {Field, FieldDefinition, Form, initializationDefinition} from "../../../../../../types/mobx-react-form";
import {Validations} from "../../lib/vjf_rules";
import {WebLoginModel, WebUserSignInOut} from "../../lib/api/sign_in";
diff --git a/javascripts/src/components/session_login_page/SessionLoginPage.tsx b/app/javascript/legacy_react/src/components/session_login_page/SessionLoginPage.tsx
similarity index 100%
rename from javascripts/src/components/session_login_page/SessionLoginPage.tsx
rename to app/javascript/legacy_react/src/components/session_login_page/SessionLoginPage.tsx
diff --git a/javascripts/src/lib/api/create_offsite_donation.ts b/app/javascript/legacy_react/src/lib/api/create_offsite_donation.ts
similarity index 92%
rename from javascripts/src/lib/api/create_offsite_donation.ts
rename to app/javascript/legacy_react/src/lib/api/create_offsite_donation.ts
index 9abe4d3f..d54ba985 100644
--- a/javascripts/src/lib/api/create_offsite_donation.ts
+++ b/app/javascript/legacy_react/src/lib/api/create_offsite_donation.ts
@@ -58,11 +58,11 @@ export class CreateOffsiteDonation {
}
if (extraJQueryAjaxSettings) {
- requestOptions = (Object).assign(requestOptions, extraJQueryAjaxSettings);
+ requestOptions = Object.assign(requestOptions, extraJQueryAjaxSettings);
}
if (this.defaultExtraJQueryAjaxSettings) {
- requestOptions = (Object).assign(requestOptions, this.defaultExtraJQueryAjaxSettings);
+ requestOptions = Object.assign(requestOptions, this.defaultExtraJQueryAjaxSettings);
}
let dfd = $.Deferred();
@@ -76,7 +76,7 @@ export class CreateOffsiteDonation {
}
);
- return dfd.promise();
+ return dfd.promise() as any;
}
}
diff --git a/javascripts/src/lib/api/put_donation.ts b/app/javascript/legacy_react/src/lib/api/put_donation.ts
similarity index 92%
rename from javascripts/src/lib/api/put_donation.ts
rename to app/javascript/legacy_react/src/lib/api/put_donation.ts
index c1cd81cc..e573f113 100644
--- a/javascripts/src/lib/api/put_donation.ts
+++ b/app/javascript/legacy_react/src/lib/api/put_donation.ts
@@ -58,11 +58,11 @@ export class PutDonation {
}
if (extraJQueryAjaxSettings) {
- requestOptions = (Object).assign(requestOptions, extraJQueryAjaxSettings);
+ requestOptions = Object.assign(requestOptions, extraJQueryAjaxSettings);
}
if (this.defaultExtraJQueryAjaxSettings) {
- requestOptions = (Object).assign(requestOptions, this.defaultExtraJQueryAjaxSettings);
+ requestOptions = Object.assign(requestOptions, this.defaultExtraJQueryAjaxSettings);
}
let dfd = $.Deferred();
@@ -76,7 +76,7 @@ export class PutDonation {
}
);
- return dfd.promise();
+ return dfd.promise() as any;
}
}
diff --git a/javascripts/src/lib/api/sign_in.ts b/app/javascript/legacy_react/src/lib/api/sign_in.ts
similarity index 91%
rename from javascripts/src/lib/api/sign_in.ts
rename to app/javascript/legacy_react/src/lib/api/sign_in.ts
index 55dce752..e5fb4724 100644
--- a/javascripts/src/lib/api/sign_in.ts
+++ b/app/javascript/legacy_react/src/lib/api/sign_in.ts
@@ -58,11 +58,11 @@ export class WebUserSignInOut {
}
if (extraJQueryAjaxSettings) {
- requestOptions = (Object).assign(requestOptions, extraJQueryAjaxSettings);
+ requestOptions = Object.assign(requestOptions, extraJQueryAjaxSettings);
}
if (this.defaultExtraJQueryAjaxSettings) {
- requestOptions = (Object).assign(requestOptions, this.defaultExtraJQueryAjaxSettings);
+ requestOptions = Object.assign(requestOptions, this.defaultExtraJQueryAjaxSettings);
}
let dfd = $.Deferred();
@@ -76,7 +76,7 @@ export class WebUserSignInOut {
}
);
- return dfd.promise();
+ return dfd.promise() as any;
}
}
diff --git a/javascripts/src/lib/api_manager.spec.ts b/app/javascript/legacy_react/src/lib/api_manager.spec.ts
similarity index 100%
rename from javascripts/src/lib/api_manager.spec.ts
rename to app/javascript/legacy_react/src/lib/api_manager.spec.ts
diff --git a/javascripts/src/lib/api_manager.ts b/app/javascript/legacy_react/src/lib/api_manager.ts
similarity index 94%
rename from javascripts/src/lib/api_manager.ts
rename to app/javascript/legacy_react/src/lib/api_manager.ts
index 512fa6d6..c15aa3eb 100644
--- a/javascripts/src/lib/api_manager.ts
+++ b/app/javascript/legacy_react/src/lib/api_manager.ts
@@ -27,10 +27,10 @@ export class ApiManager {
let newed = new i()
if (beforeSendInterceptors && beforeSendInterceptors.length > 0) {
let a: JQuery.AjaxSettings = {
- beforeSend: ((jqXHR:JQuery.jqXHR, settings:JQuery.AjaxSettings) : false|void => {
+ beforeSend: ((jqXHR:JQuery.jqXHR, settings:JQuery.AjaxSettings) : false|void => {
_.forEach(beforeSendInterceptors, (i:Interceptor) => i(jqXHR, settings))
return
- })
+ }) as any
}
newed.defaultExtraJQueryAjaxSettings = a
}
diff --git a/javascripts/src/lib/apis.ts b/app/javascript/legacy_react/src/lib/apis.ts
similarity index 100%
rename from javascripts/src/lib/apis.ts
rename to app/javascript/legacy_react/src/lib/apis.ts
diff --git a/javascripts/src/lib/createNumberMask.spec.ts b/app/javascript/legacy_react/src/lib/createNumberMask.spec.ts
similarity index 100%
rename from javascripts/src/lib/createNumberMask.spec.ts
rename to app/javascript/legacy_react/src/lib/createNumberMask.spec.ts
diff --git a/javascripts/src/lib/createNumberMask.ts b/app/javascript/legacy_react/src/lib/createNumberMask.ts
similarity index 100%
rename from javascripts/src/lib/createNumberMask.ts
rename to app/javascript/legacy_react/src/lib/createNumberMask.ts
diff --git a/javascripts/src/lib/csrf_interceptor.ts b/app/javascript/legacy_react/src/lib/csrf_interceptor.ts
similarity index 83%
rename from javascripts/src/lib/csrf_interceptor.ts
rename to app/javascript/legacy_react/src/lib/csrf_interceptor.ts
index dea0db9c..ff129012 100644
--- a/javascripts/src/lib/csrf_interceptor.ts
+++ b/app/javascript/legacy_react/src/lib/csrf_interceptor.ts
@@ -6,6 +6,6 @@
* @returns {false | void}
*/
export function CSRFInterceptor(this:any, jqXHR:JQuery.jqXHR, settings: JQuery.AjaxSettings): false|void {
- jqXHR.setRequestHeader('X-CSRF-Token', (window)._csrf)
+ jqXHR.setRequestHeader('X-CSRF-Token', (window as any)._csrf)
}
diff --git a/javascripts/src/lib/date.ts b/app/javascript/legacy_react/src/lib/date.ts
similarity index 98%
rename from javascripts/src/lib/date.ts
rename to app/javascript/legacy_react/src/lib/date.ts
index 86ecdb7d..98695365 100644
--- a/javascripts/src/lib/date.ts
+++ b/app/javascript/legacy_react/src/lib/date.ts
@@ -1,5 +1,5 @@
// License: LGPL-3.0-or-later
-import * as moment from 'moment';
+import moment from 'moment';
import 'moment-timezone'
function momentTz(date:string, timezone:string='UTC'):moment.Moment {
diff --git a/javascripts/src/lib/dedication.ts b/app/javascript/legacy_react/src/lib/dedication.ts
similarity index 100%
rename from javascripts/src/lib/dedication.ts
rename to app/javascript/legacy_react/src/lib/dedication.ts
diff --git a/javascripts/src/lib/deprecated_format.ts b/app/javascript/legacy_react/src/lib/deprecated_format.ts
similarity index 100%
rename from javascripts/src/lib/deprecated_format.ts
rename to app/javascript/legacy_react/src/lib/deprecated_format.ts
diff --git a/javascripts/src/lib/format.spec.ts b/app/javascript/legacy_react/src/lib/format.spec.ts
similarity index 100%
rename from javascripts/src/lib/format.spec.ts
rename to app/javascript/legacy_react/src/lib/format.spec.ts
diff --git a/javascripts/src/lib/format.ts b/app/javascript/legacy_react/src/lib/format.ts
similarity index 100%
rename from javascripts/src/lib/format.ts
rename to app/javascript/legacy_react/src/lib/format.ts
diff --git a/javascripts/src/lib/houdini_form.ts b/app/javascript/legacy_react/src/lib/houdini_form.ts
similarity index 99%
rename from javascripts/src/lib/houdini_form.ts
rename to app/javascript/legacy_react/src/lib/houdini_form.ts
index a40c2cbd..726d7a15 100644
--- a/javascripts/src/lib/houdini_form.ts
+++ b/app/javascript/legacy_react/src/lib/houdini_form.ts
@@ -3,7 +3,7 @@ import {Field, FieldDefinition, Form, initializationDefinition} from "mobx-react
import {action, computed, IValueDidChange, observable, runInAction} from 'mobx'
import * as _ from 'lodash'
import {ValidationErrorsException} from "../../api";
-import validator = require("validator");
+import validator from "validator";
export class HoudiniForm extends Form {
diff --git a/javascripts/src/lib/mobx_utils.ts b/app/javascript/legacy_react/src/lib/mobx_utils.ts
similarity index 100%
rename from javascripts/src/lib/mobx_utils.ts
rename to app/javascript/legacy_react/src/lib/mobx_utils.ts
diff --git a/javascripts/src/lib/nonprofitBranding.ts b/app/javascript/legacy_react/src/lib/nonprofitBranding.ts
similarity index 95%
rename from javascripts/src/lib/nonprofitBranding.ts
rename to app/javascript/legacy_react/src/lib/nonprofitBranding.ts
index b05f5d43..d9ee335c 100644
--- a/javascripts/src/lib/nonprofitBranding.ts
+++ b/app/javascript/legacy_react/src/lib/nonprofitBranding.ts
@@ -1,5 +1,5 @@
// License: LGPL-3.0-or-later
-import color = require('color')
+import color from 'color';
import { Color } from 'csstype';
interface CustomBrandColors {
diff --git a/javascripts/src/lib/payments/credit_card.spec.ts b/app/javascript/legacy_react/src/lib/payments/credit_card.spec.ts
similarity index 99%
rename from javascripts/src/lib/payments/credit_card.spec.ts
rename to app/javascript/legacy_react/src/lib/payments/credit_card.spec.ts
index 8edfcabf..29bb2bc4 100644
--- a/javascripts/src/lib/payments/credit_card.spec.ts
+++ b/app/javascript/legacy_react/src/lib/payments/credit_card.spec.ts
@@ -191,7 +191,7 @@ describe('CreditCardTypeManager', () => {
})
it('should support year shorthand', () => {
- expect(cc.validateCardExpiry('05', '20')).toBeTruthy()
+ expect(cc.validateCardExpiry('05', '25')).toBeTruthy()
})
})
describe('Validating a CVC number', () => {
diff --git a/javascripts/src/lib/payments/credit_card.ts b/app/javascript/legacy_react/src/lib/payments/credit_card.ts
similarity index 100%
rename from javascripts/src/lib/payments/credit_card.ts
rename to app/javascript/legacy_react/src/lib/payments/credit_card.ts
diff --git a/javascripts/src/lib/regex.spec.ts b/app/javascript/legacy_react/src/lib/regex.spec.ts
similarity index 100%
rename from javascripts/src/lib/regex.spec.ts
rename to app/javascript/legacy_react/src/lib/regex.spec.ts
diff --git a/javascripts/src/lib/regex.ts b/app/javascript/legacy_react/src/lib/regex.ts
similarity index 100%
rename from javascripts/src/lib/regex.ts
rename to app/javascript/legacy_react/src/lib/regex.ts
diff --git a/javascripts/src/lib/tests/helpers.ts b/app/javascript/legacy_react/src/lib/tests/helpers.ts
similarity index 100%
rename from javascripts/src/lib/tests/helpers.ts
rename to app/javascript/legacy_react/src/lib/tests/helpers.ts
diff --git a/javascripts/src/lib/utils.ts b/app/javascript/legacy_react/src/lib/utils.ts
similarity index 100%
rename from javascripts/src/lib/utils.ts
rename to app/javascript/legacy_react/src/lib/utils.ts
diff --git a/javascripts/src/lib/vjf_rules.ts b/app/javascript/legacy_react/src/lib/vjf_rules.ts
similarity index 98%
rename from javascripts/src/lib/vjf_rules.ts
rename to app/javascript/legacy_react/src/lib/vjf_rules.ts
index 26eef445..b9f2db7f 100644
--- a/javascripts/src/lib/vjf_rules.ts
+++ b/app/javascript/legacy_react/src/lib/vjf_rules.ts
@@ -1,7 +1,7 @@
// License: LGPL-3.0-or-later
import * as Regex from './regex'
import {Field, Form} from "mobx-react-form";
-import moment = require("moment");
+import moment from "moment";
interface ValidationInput {
diff --git a/app/javascript/packs/create_new_offsite_payment_pane.js b/app/javascript/packs/create_new_offsite_payment_pane.js
new file mode 100644
index 00000000..71a6323c
--- /dev/null
+++ b/app/javascript/packs/create_new_offsite_payment_pane.js
@@ -0,0 +1,4 @@
+// License: LGPL-3.0-or-later
+// require a root component here. This will be treated as the root of a webpack package
+require('bootstrap-loader');
+require('../legacy_react/app/create_new_offsite_payment_pane')
\ No newline at end of file
diff --git a/app/javascript/packs/donate-button-v2.js b/app/javascript/packs/donate-button-v2.js
new file mode 100644
index 00000000..83d5dfe6
--- /dev/null
+++ b/app/javascript/packs/donate-button-v2.js
@@ -0,0 +1 @@
+require('../donate-button/donate-button.v2')
\ No newline at end of file
diff --git a/app/javascript/packs/edit_payment_pane.js b/app/javascript/packs/edit_payment_pane.js
new file mode 100644
index 00000000..3b85237a
--- /dev/null
+++ b/app/javascript/packs/edit_payment_pane.js
@@ -0,0 +1,4 @@
+// License: LGPL-3.0-or-later
+// require a root component here. This will be treated as the root of a webpack package
+require('bootstrap-loader');
+require('../legacy_react/app/edit_payment_pane')
\ No newline at end of file
diff --git a/app/javascript/packs/i18n.js b/app/javascript/packs/i18n.js
new file mode 100644
index 00000000..521ee32c
--- /dev/null
+++ b/app/javascript/packs/i18n.js
@@ -0,0 +1,3 @@
+const i18n = require('../i18n.js.erb')
+
+window.I18n = i18n;
\ No newline at end of file
diff --git a/app/javascript/packs/loading_indicator.ts b/app/javascript/packs/loading_indicator.ts
new file mode 100644
index 00000000..86d287c4
--- /dev/null
+++ b/app/javascript/packs/loading_indicator.ts
@@ -0,0 +1,8 @@
+// License: LGPL-3.0-or-later
+require('../legacy_react/app/loading_indicator')
+
+
+
+
+
+
diff --git a/app/javascript/packs/page__bank_accounts__confirm.js b/app/javascript/packs/page__bank_accounts__confirm.js
new file mode 100644
index 00000000..7a8a575e
--- /dev/null
+++ b/app/javascript/packs/page__bank_accounts__confirm.js
@@ -0,0 +1,3 @@
+require('../../../client/css/global/page.css')
+require('../legacy/page.js')
+require('../legacy/bank_accounts/confirm/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/page__campaigns__index.js b/app/javascript/packs/page__campaigns__index.js
new file mode 100644
index 00000000..7d8d84b6
--- /dev/null
+++ b/app/javascript/packs/page__campaigns__index.js
@@ -0,0 +1,3 @@
+require('../../../client/css/global/page.css')
+require('../legacy/page.js')
+require('../legacy/campaigns/index/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/page__campaigns__peer_to_peer.js b/app/javascript/packs/page__campaigns__peer_to_peer.js
new file mode 100644
index 00000000..9c88a1be
--- /dev/null
+++ b/app/javascript/packs/page__campaigns__peer_to_peer.js
@@ -0,0 +1,3 @@
+require('../../../client/css/global/page.css')
+require('../legacy/page.js')
+require('../legacy/campaigns/peer_to_peer/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/page__campaigns__show.js b/app/javascript/packs/page__campaigns__show.js
new file mode 100644
index 00000000..abff9f6e
--- /dev/null
+++ b/app/javascript/packs/page__campaigns__show.js
@@ -0,0 +1,3 @@
+require('../../../client/css/global/page.css')
+require('../legacy/page.js')
+require('../legacy/campaigns/show/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/page__campaigns__supporters__index.js b/app/javascript/packs/page__campaigns__supporters__index.js
new file mode 100644
index 00000000..201c25c0
--- /dev/null
+++ b/app/javascript/packs/page__campaigns__supporters__index.js
@@ -0,0 +1,3 @@
+require('../../../client/css/global/page.css')
+require('../legacy/page.js')
+require('../legacy/campaigns/supporters/index/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/page__events__index.js b/app/javascript/packs/page__events__index.js
new file mode 100644
index 00000000..95ee1fd0
--- /dev/null
+++ b/app/javascript/packs/page__events__index.js
@@ -0,0 +1,3 @@
+require('../../../client/css/global/page.css')
+require('../legacy/page.js')
+require('../legacy/events/index/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/page__events__show.js b/app/javascript/packs/page__events__show.js
new file mode 100644
index 00000000..989c1498
--- /dev/null
+++ b/app/javascript/packs/page__events__show.js
@@ -0,0 +1,3 @@
+require('../../../client/css/global/page.css')
+require('../legacy/page.js')
+require('../legacy/events/show/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/page__events__stats.js b/app/javascript/packs/page__events__stats.js
new file mode 100644
index 00000000..f3f17718
--- /dev/null
+++ b/app/javascript/packs/page__events__stats.js
@@ -0,0 +1,3 @@
+require('../../../client/css/global/page.css')
+require('../legacy/page.js')
+require('../legacy/events/stats/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/page__nonprofits__btn.js b/app/javascript/packs/page__nonprofits__btn.js
new file mode 100644
index 00000000..51cf0b41
--- /dev/null
+++ b/app/javascript/packs/page__nonprofits__btn.js
@@ -0,0 +1,3 @@
+require('../../../client/css/global/page.css')
+require('../legacy/page.js')
+require('../legacy/nonprofits/btn/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/page__nonprofits__button.js b/app/javascript/packs/page__nonprofits__button.js
new file mode 100644
index 00000000..78f16c5b
--- /dev/null
+++ b/app/javascript/packs/page__nonprofits__button.js
@@ -0,0 +1,3 @@
+require('../../../client/css/global/page.css')
+require('../legacy/page.js')
+require('../legacy/nonprofits/button/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/page__nonprofits__cards__edit.js b/app/javascript/packs/page__nonprofits__cards__edit.js
new file mode 100644
index 00000000..e3be4ae0
--- /dev/null
+++ b/app/javascript/packs/page__nonprofits__cards__edit.js
@@ -0,0 +1,3 @@
+require('../../../client/css/global/page.css')
+require('../legacy/page.js')
+require('../legacy/nonprofits/cards/edit/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/page__nonprofits__dashboard.js b/app/javascript/packs/page__nonprofits__dashboard.js
new file mode 100644
index 00000000..fc7ef4f1
--- /dev/null
+++ b/app/javascript/packs/page__nonprofits__dashboard.js
@@ -0,0 +1,3 @@
+require('../../../client/css/global/page.css')
+require('../legacy/page.js')
+require('../legacy/nonprofits/dashboard/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/page__nonprofits__donate.js b/app/javascript/packs/page__nonprofits__donate.js
new file mode 100644
index 00000000..b36bf4cc
--- /dev/null
+++ b/app/javascript/packs/page__nonprofits__donate.js
@@ -0,0 +1,2 @@
+require('../legacy/page.js')
+require('../legacy/nonprofits/donate/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/page__nonprofits__edit.js b/app/javascript/packs/page__nonprofits__edit.js
new file mode 100644
index 00000000..aacb30d1
--- /dev/null
+++ b/app/javascript/packs/page__nonprofits__edit.js
@@ -0,0 +1,3 @@
+require('../../../client/css/global/page.css')
+require('../legacy/page.js')
+require('../legacy/nonprofits/edit/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/page__nonprofits__payments__index.js b/app/javascript/packs/page__nonprofits__payments__index.js
new file mode 100644
index 00000000..866269b8
--- /dev/null
+++ b/app/javascript/packs/page__nonprofits__payments__index.js
@@ -0,0 +1,3 @@
+require('../../../client/css/global/page.css')
+require('../legacy/page.js')
+require('../legacy/nonprofits/payments/index/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/page__nonprofits__payouts__index.js b/app/javascript/packs/page__nonprofits__payouts__index.js
new file mode 100644
index 00000000..5bbbd972
--- /dev/null
+++ b/app/javascript/packs/page__nonprofits__payouts__index.js
@@ -0,0 +1,3 @@
+require('../../../client/css/global/page.css')
+require('../legacy/page.js')
+require('../legacy/nonprofits/payouts/index/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/page__nonprofits__recurring_donations__index.js b/app/javascript/packs/page__nonprofits__recurring_donations__index.js
new file mode 100644
index 00000000..8f60a736
--- /dev/null
+++ b/app/javascript/packs/page__nonprofits__recurring_donations__index.js
@@ -0,0 +1,3 @@
+require('../../../client/css/global/page.css')
+require('../legacy/page.js')
+require('../legacy/nonprofits/recurring_donations/index/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/page__nonprofits__show.js b/app/javascript/packs/page__nonprofits__show.js
new file mode 100644
index 00000000..7035699f
--- /dev/null
+++ b/app/javascript/packs/page__nonprofits__show.js
@@ -0,0 +1,3 @@
+require('../../../client/css/global/page.css')
+require('../legacy/page.js')
+require('../legacy/nonprofits/show/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/page__nonprofits__supporter_form.js b/app/javascript/packs/page__nonprofits__supporter_form.js
new file mode 100644
index 00000000..94f8e768
--- /dev/null
+++ b/app/javascript/packs/page__nonprofits__supporter_form.js
@@ -0,0 +1,3 @@
+require('../../../client/css/global/page.css')
+require('../legacy/page.js')
+require('../legacy/nonprofits/supporter_form/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/page__nonprofits__supporters__index.js b/app/javascript/packs/page__nonprofits__supporters__index.js
new file mode 100644
index 00000000..f408b7c8
--- /dev/null
+++ b/app/javascript/packs/page__nonprofits__supporters__index.js
@@ -0,0 +1,2 @@
+require('../legacy/page.js')
+require('../legacy/nonprofits/supporters/index/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/page__nonprofits__supporters__new.js b/app/javascript/packs/page__nonprofits__supporters__new.js
new file mode 100644
index 00000000..693ff9c2
--- /dev/null
+++ b/app/javascript/packs/page__nonprofits__supporters__new.js
@@ -0,0 +1,3 @@
+require('../../../client/css/global/page.css')
+require('../legacy/page.js')
+require('../legacy/nonprofits/supporters/new/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/page__profiles__donations_history.js b/app/javascript/packs/page__profiles__donations_history.js
new file mode 100644
index 00000000..10da02c3
--- /dev/null
+++ b/app/javascript/packs/page__profiles__donations_history.js
@@ -0,0 +1 @@
+require('../legacy/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/page__profiles__fundraisers.js b/app/javascript/packs/page__profiles__fundraisers.js
new file mode 100644
index 00000000..10da02c3
--- /dev/null
+++ b/app/javascript/packs/page__profiles__fundraisers.js
@@ -0,0 +1 @@
+require('../legacy/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/page__profiles__show.js b/app/javascript/packs/page__profiles__show.js
new file mode 100644
index 00000000..10da02c3
--- /dev/null
+++ b/app/javascript/packs/page__profiles__show.js
@@ -0,0 +1 @@
+require('../legacy/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/page__recurring_donations__edit.js b/app/javascript/packs/page__recurring_donations__edit.js
new file mode 100644
index 00000000..d77b9aa5
--- /dev/null
+++ b/app/javascript/packs/page__recurring_donations__edit.js
@@ -0,0 +1,3 @@
+require('../../../client/css/global/page.css')
+require('../legacy/page.js')
+require('../legacy/recurring_donations/edit/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/page__settings__index.js b/app/javascript/packs/page__settings__index.js
new file mode 100644
index 00000000..767aca08
--- /dev/null
+++ b/app/javascript/packs/page__settings__index.js
@@ -0,0 +1,3 @@
+require('../../../client/css/global/page.css')
+require('../legacy/page.js')
+require('../legacy/settings/index/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/page__stripe_wrapper.js b/app/javascript/packs/page__stripe_wrapper.js
new file mode 100644
index 00000000..a27ca2c2
--- /dev/null
+++ b/app/javascript/packs/page__stripe_wrapper.js
@@ -0,0 +1 @@
+require('../legacy/stripe_wrapper/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/page__super-admin.js b/app/javascript/packs/page__super-admin.js
new file mode 100644
index 00000000..fb362949
--- /dev/null
+++ b/app/javascript/packs/page__super-admin.js
@@ -0,0 +1,3 @@
+require('../../../client/css/global/page.css')
+require('../legacy/page.js')
+require('../legacy/super-admin/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/page__tickets__index.js b/app/javascript/packs/page__tickets__index.js
new file mode 100644
index 00000000..5fe6f413
--- /dev/null
+++ b/app/javascript/packs/page__tickets__index.js
@@ -0,0 +1,3 @@
+require('../../../client/css/global/page.css')
+require('../legacy/page.js')
+require('../legacy/tickets/index/page.js')
\ No newline at end of file
diff --git a/app/javascript/packs/registration_page.js b/app/javascript/packs/registration_page.js
new file mode 100644
index 00000000..7c93fb67
--- /dev/null
+++ b/app/javascript/packs/registration_page.js
@@ -0,0 +1,4 @@
+// License: LGPL-3.0-or-later
+require('bootstrap-loader');
+require('../legacy_react/app/registration_page')
+
diff --git a/app/javascript/packs/session_login_page.js b/app/javascript/packs/session_login_page.js
new file mode 100644
index 00000000..7e7147b2
--- /dev/null
+++ b/app/javascript/packs/session_login_page.js
@@ -0,0 +1,3 @@
+// License: LGPL-3.0-or-later
+require('bootstrap-loader');
+require('../legacy_react/app/session_login_page')
\ No newline at end of file
diff --git a/app/javascript/page_info.js.erb b/app/javascript/page_info.js.erb
new file mode 100644
index 00000000..dba524ba
--- /dev/null
+++ b/app/javascript/page_info.js.erb
@@ -0,0 +1,5 @@
+const pageInfo = {
+ apiDomain: '<%= Settings.api_domain.url %>'
+}
+
+module.exports = pageInfo;
\ No newline at end of file
diff --git a/app/jobs/admin_failed_gift_job.rb b/app/jobs/admin_failed_gift_job.rb
new file mode 100644
index 00000000..15f38693
--- /dev/null
+++ b/app/jobs/admin_failed_gift_job.rb
@@ -0,0 +1,6 @@
+class AdminFailedGiftJob < EmailJob
+
+ def perform(donation, campaign_gift_option)
+ AdminMailer.notify_failed_gift(donation, campaign_gift_option).deliver_now
+ end
+end
diff --git a/app/api/houdini/v1/entities/nonprofit.rb b/app/jobs/application_job.rb
similarity index 54%
rename from app/api/houdini/v1/entities/nonprofit.rb
rename to app/jobs/application_job.rb
index 55620d7e..d4046c71 100644
--- a/app/api/houdini/v1/entities/nonprofit.rb
+++ b/app/jobs/application_job.rb
@@ -1,4 +1,6 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class Houdini::V1::Entities::Nonprofit < Grape::Entity
- expose :id
-end
\ No newline at end of file
+
+class ApplicationJob < ActiveJob::Base
+end
diff --git a/app/jobs/bank_account_create_job.rb b/app/jobs/bank_account_create_job.rb
new file mode 100644
index 00000000..f30c5c23
--- /dev/null
+++ b/app/jobs/bank_account_create_job.rb
@@ -0,0 +1,6 @@
+class BankAccountCreateJob < EmailJob
+
+ def perform(bank_account)
+ NonprofitMailer.new_bank_account_notification(bank_account).deliver_now
+ end
+end
diff --git a/app/jobs/campaign_creation_email_followup_job.rb b/app/jobs/campaign_creation_email_followup_job.rb
new file mode 100644
index 00000000..2ed45890
--- /dev/null
+++ b/app/jobs/campaign_creation_email_followup_job.rb
@@ -0,0 +1,6 @@
+class CampaignCreationEmailFollowupJob < EmailJob
+
+ def perform(campaign)
+ CampaignMailer.creation_followup(campaign).deliver_now
+ end
+end
diff --git a/app/jobs/campaign_creation_federated_email_job.rb b/app/jobs/campaign_creation_federated_email_job.rb
new file mode 100644
index 00000000..c80d8f90
--- /dev/null
+++ b/app/jobs/campaign_creation_federated_email_job.rb
@@ -0,0 +1,6 @@
+class CampaignCreationFederatedEmailJob < EmailJob
+
+ def perform(campaign)
+ CampaignMailer.federated_creation_followup(campaign).deliver_now
+ end
+end
diff --git a/app/jobs/direct_debit_create_notify_donor_job.rb b/app/jobs/direct_debit_create_notify_donor_job.rb
new file mode 100644
index 00000000..d720fc32
--- /dev/null
+++ b/app/jobs/direct_debit_create_notify_donor_job.rb
@@ -0,0 +1,6 @@
+class DirectDebitCreateNotifyDonorJob < EmailJob
+
+ def perform(donation_id, locale)
+ DonationMailer.donor_direct_debit_notification(donation_id, locale).deliver_now
+ end
+end
diff --git a/app/jobs/direct_debit_create_notify_nonprofit_job.rb b/app/jobs/direct_debit_create_notify_nonprofit_job.rb
new file mode 100644
index 00000000..56767564
--- /dev/null
+++ b/app/jobs/direct_debit_create_notify_nonprofit_job.rb
@@ -0,0 +1,6 @@
+class DirectDebitCreateNotifyNonprofitJob < EmailJob
+
+ def perform(donation_id)
+ DonationMailer.nonprofit_payment_notification(donation_id).deliver_now
+ end
+end
diff --git a/app/jobs/email_job.rb b/app/jobs/email_job.rb
new file mode 100644
index 00000000..e30bd65c
--- /dev/null
+++ b/app/jobs/email_job.rb
@@ -0,0 +1,5 @@
+class EmailJob < ApplicationJob
+ queue_as :email_queue
+
+ retry_on Exception, wait: ->(executions) { executions **2.195 }, attempts: MAX_EMAIL_JOB_ATTEMPTS || 1
+end
diff --git a/app/jobs/email_list_create_job.rb b/app/jobs/email_list_create_job.rb
new file mode 100644
index 00000000..21795976
--- /dev/null
+++ b/app/jobs/email_list_create_job.rb
@@ -0,0 +1,7 @@
+class EmailListCreateJob < ApplicationJob
+ queue_as :default
+
+ def perform(npo_id)
+ UpdateEmailLists.populate_lists_on_mailchimp(npo_id)
+ end
+end
diff --git a/app/jobs/event_create_creator_email_job.rb b/app/jobs/event_create_creator_email_job.rb
new file mode 100644
index 00000000..391b936e
--- /dev/null
+++ b/app/jobs/event_create_creator_email_job.rb
@@ -0,0 +1,6 @@
+class EventCreateCreatorEmailJob < EmailJob
+
+ def perform(event)
+ EventMailer.creation_followup(event).deliver_now
+ end
+end
diff --git a/app/jobs/event_create_job.rb b/app/jobs/event_create_job.rb
new file mode 100644
index 00000000..561a775a
--- /dev/null
+++ b/app/jobs/event_create_job.rb
@@ -0,0 +1,7 @@
+class EventCreateJob < ApplicationJob
+ queue_as :default
+
+ def perform(event)
+ EventCreateCreatorEmailJob.perform_later(event)
+ end
+end
diff --git a/app/jobs/export_payments_completed_job.rb b/app/jobs/export_payments_completed_job.rb
new file mode 100644
index 00000000..49619415
--- /dev/null
+++ b/app/jobs/export_payments_completed_job.rb
@@ -0,0 +1,6 @@
+class ExportPaymentsCompletedJob < EmailJob
+
+ def perform(export)
+ ExportMailer.export_payments_completed_notification(export).deliver_now
+ end
+end
diff --git a/app/jobs/export_payments_failed_job.rb b/app/jobs/export_payments_failed_job.rb
new file mode 100644
index 00000000..8acbcb2a
--- /dev/null
+++ b/app/jobs/export_payments_failed_job.rb
@@ -0,0 +1,6 @@
+class ExportPaymentsFailedJob < EmailJob
+
+ def perform(export)
+ ExportMailer.export_payments_failed_notification(export).deliver_now
+ end
+end
diff --git a/app/jobs/export_recurring_donations_completed_job.rb b/app/jobs/export_recurring_donations_completed_job.rb
new file mode 100644
index 00000000..245dfdda
--- /dev/null
+++ b/app/jobs/export_recurring_donations_completed_job.rb
@@ -0,0 +1,6 @@
+class ExportRecurringDonationsCompletedJob < EmailJob
+
+ def perform(export)
+ ExportMailer.export_recurring_donations_completed_notification(@export).deliver_now
+ end
+end
diff --git a/app/jobs/export_recurring_donations_failed_job.rb b/app/jobs/export_recurring_donations_failed_job.rb
new file mode 100644
index 00000000..b1dd904e
--- /dev/null
+++ b/app/jobs/export_recurring_donations_failed_job.rb
@@ -0,0 +1,6 @@
+class ExportRecurringDonationsFailedJob < EmailJob
+
+ def perform(export)
+ ExportMailer.export_recurring_donations_failed_notification(export).deliver_now
+ end
+end
diff --git a/app/jobs/export_supporter_notes_completed_job.rb b/app/jobs/export_supporter_notes_completed_job.rb
new file mode 100644
index 00000000..bfcf9993
--- /dev/null
+++ b/app/jobs/export_supporter_notes_completed_job.rb
@@ -0,0 +1,6 @@
+class ExportSupporterNotesCompletedJob < EmailJob
+
+ def perform(export)
+ ExportMailer.export_supporter_notes_completed_notification(export).deliver_now
+ end
+end
diff --git a/app/jobs/export_supporter_notes_failed_job.rb b/app/jobs/export_supporter_notes_failed_job.rb
new file mode 100644
index 00000000..ba59a7ba
--- /dev/null
+++ b/app/jobs/export_supporter_notes_failed_job.rb
@@ -0,0 +1,6 @@
+class ExportSupporterNotesFailedJob < EmailJob
+
+ def perform(export)
+ ExportMailer.export_supporter_notes_failed_notification(export).deliver_now
+ end
+end
diff --git a/app/jobs/export_supporters_completed_job.rb b/app/jobs/export_supporters_completed_job.rb
new file mode 100644
index 00000000..0d06045f
--- /dev/null
+++ b/app/jobs/export_supporters_completed_job.rb
@@ -0,0 +1,6 @@
+class ExportSupportersCompletedJob < EmailJob
+
+ def perform(export)
+ ExportMailer.export_supporters_completed_notification(export).deliver_now
+ end
+end
diff --git a/app/jobs/export_supporters_failed_job.rb b/app/jobs/export_supporters_failed_job.rb
new file mode 100644
index 00000000..4da0f375
--- /dev/null
+++ b/app/jobs/export_supporters_failed_job.rb
@@ -0,0 +1,6 @@
+class ExportSupportersFailedJob < EmailJob
+
+ def perform(export)
+ ExportMailer.export_supporters_failed_notification(export).deliver_now
+ end
+end
diff --git a/app/jobs/failed_recurring_donation_payment_donor_email_job.rb b/app/jobs/failed_recurring_donation_payment_donor_email_job.rb
new file mode 100644
index 00000000..90054cd4
--- /dev/null
+++ b/app/jobs/failed_recurring_donation_payment_donor_email_job.rb
@@ -0,0 +1,6 @@
+class FailedRecurringDonationPaymentDonorEmailJob < EmailJob
+
+ def perform(donation)
+ DonationMailer.donor_failed_recurring_donation(donation.id).deliver_now
+ end
+end
diff --git a/app/jobs/failed_recurring_donation_payment_nonprofit_email_job.rb b/app/jobs/failed_recurring_donation_payment_nonprofit_email_job.rb
new file mode 100644
index 00000000..c9ed53a7
--- /dev/null
+++ b/app/jobs/failed_recurring_donation_payment_nonprofit_email_job.rb
@@ -0,0 +1,6 @@
+class FailedRecurringDonationPaymentNonprofitEmailJob < EmailJob
+
+ def perform(donation)
+ DonationMailer.nonprofit_failed_recurring_donation(donation.id).deliver_now
+ end
+end
diff --git a/app/jobs/import_completed_job.rb b/app/jobs/import_completed_job.rb
new file mode 100644
index 00000000..82fb6336
--- /dev/null
+++ b/app/jobs/import_completed_job.rb
@@ -0,0 +1,6 @@
+class ImportCompletedJob < EmailJob
+
+ def perform(import)
+ ImportMailer.import_completed_notification(import.id).deliver_now
+ end
+end
diff --git a/app/jobs/import_creation_job.rb b/app/jobs/import_creation_job.rb
new file mode 100644
index 00000000..97c24f0d
--- /dev/null
+++ b/app/jobs/import_creation_job.rb
@@ -0,0 +1,13 @@
+class ImportCreationJob < ApplicationJob
+ queue_as :default
+
+ def perform(import_params, current_user)
+ InsertImport.from_csv_safe(
+ nonprofit_id: import_params[:nonprofit_id],
+ user_id: current_user.id,
+ user_email: current_user.email,
+ file_uri: import_params[:file_uri],
+ header_matches: import_params[:header_matches]
+ )
+ end
+end
diff --git a/app/jobs/mailchimp_supporter_sync_job.rb b/app/jobs/mailchimp_supporter_sync_job.rb
new file mode 100644
index 00000000..557c9368
--- /dev/null
+++ b/app/jobs/mailchimp_supporter_sync_job.rb
@@ -0,0 +1,7 @@
+class MailchimpSupporterSyncJob < ApplicationJob
+ queue_as :default
+
+ def perform(np_id, supporter_ids, tag_data)
+ Mailchimp.sync_supporters_to_list_from_tag_joins(np_id, supporter_ids, tag_data)
+ end
+end
diff --git a/app/jobs/nonprofit_create_job.rb b/app/jobs/nonprofit_create_job.rb
new file mode 100644
index 00000000..10a3c2e2
--- /dev/null
+++ b/app/jobs/nonprofit_create_job.rb
@@ -0,0 +1,6 @@
+class NonprofitCreateJob < EmailJob
+
+ def perform(nonprofit)
+ NonprofitMailer.welcome(nonprofit.id).deliver_now
+ end
+end
diff --git a/app/jobs/pay_recurring_donation_job.rb b/app/jobs/pay_recurring_donation_job.rb
new file mode 100644
index 00000000..7a64e372
--- /dev/null
+++ b/app/jobs/pay_recurring_donation_job.rb
@@ -0,0 +1,7 @@
+class PayRecurringDonationJob < ApplicationJob
+ queue_as :rec_don_payments
+
+ def perform(id)
+ PayRecurringDonation.with_stripe(id)
+ end
+end
diff --git a/app/jobs/pay_recurring_donations_job.rb b/app/jobs/pay_recurring_donations_job.rb
new file mode 100644
index 00000000..a1b51bdc
--- /dev/null
+++ b/app/jobs/pay_recurring_donations_job.rb
@@ -0,0 +1,9 @@
+class PayRecurringDonationsJob < ApplicationJob
+ queue_as :default
+
+ def perform(*ids)
+ ids.each do |id|
+ PayRecurringDonationJob.perform_later(id)
+ end
+ end
+end
diff --git a/app/jobs/payment_export_create_job.rb b/app/jobs/payment_export_create_job.rb
new file mode 100644
index 00000000..eb55e566
--- /dev/null
+++ b/app/jobs/payment_export_create_job.rb
@@ -0,0 +1,7 @@
+class PaymentExportCreateJob < ApplicationJob
+ queue_as :default
+
+ def perform(npo_id, params, user_id, export_id)
+ ExportPayments.run_export(npo_id, params, user_id, export_id)
+ end
+end
diff --git a/app/jobs/payment_notification_email_donor_job.rb b/app/jobs/payment_notification_email_donor_job.rb
new file mode 100644
index 00000000..5c49b97b
--- /dev/null
+++ b/app/jobs/payment_notification_email_donor_job.rb
@@ -0,0 +1,6 @@
+class PaymentNotificationEmailDonorJob < EmailJob
+
+ def perform(donation, locale)
+ DonationMailer.donor_payment_notification(donation.id, locale).deliver_now
+ end
+end
diff --git a/app/jobs/payment_notification_email_nonprofit_job.rb b/app/jobs/payment_notification_email_nonprofit_job.rb
new file mode 100644
index 00000000..0b246b02
--- /dev/null
+++ b/app/jobs/payment_notification_email_nonprofit_job.rb
@@ -0,0 +1,6 @@
+class PaymentNotificationEmailNonprofitJob < EmailJob
+
+ def perform(donation, user=nil)
+ DonationMailer.nonprofit_payment_notification(donation.id, user&.id).deliver_now
+ end
+end
diff --git a/app/jobs/payout_pending_job.rb b/app/jobs/payout_pending_job.rb
new file mode 100644
index 00000000..240cfe7d
--- /dev/null
+++ b/app/jobs/payout_pending_job.rb
@@ -0,0 +1,6 @@
+class PayoutPendingJob < EmailJob
+
+ def perform(payout)
+ NonprofitMailer.pending_payout_notification(payout.id).deliver_now
+ end
+end
diff --git a/app/jobs/recurring_donation_cancelled_job.rb b/app/jobs/recurring_donation_cancelled_job.rb
new file mode 100644
index 00000000..e23699c2
--- /dev/null
+++ b/app/jobs/recurring_donation_cancelled_job.rb
@@ -0,0 +1,6 @@
+class RecurringDonationCancelledJob < EmailJob
+
+ def perform(donation)
+ DonationMailer.nonprofit_recurring_donation_cancellation(donation.id).deliver_now
+ end
+end
diff --git a/app/jobs/recurring_donation_change_amount_donor_email_job.rb b/app/jobs/recurring_donation_change_amount_donor_email_job.rb
new file mode 100644
index 00000000..24aada63
--- /dev/null
+++ b/app/jobs/recurring_donation_change_amount_donor_email_job.rb
@@ -0,0 +1,6 @@
+class RecurringDonationChangeAmountDonorEmailJob < EmailJob
+
+ def perform(recurring_donation, previous_amount)
+ DonationMailer.donor_recurring_donation_change_amount(recurring_donation.id, previous_amount).deliver_now
+ end
+end
diff --git a/app/jobs/recurring_donation_change_amount_job.rb b/app/jobs/recurring_donation_change_amount_job.rb
new file mode 100644
index 00000000..e28b4e2c
--- /dev/null
+++ b/app/jobs/recurring_donation_change_amount_job.rb
@@ -0,0 +1,8 @@
+class RecurringDonationChangeAmountJob < ApplicationJob
+ queue_as :default
+
+ def perform(recurring_donation, previous_amount)
+ RecurringDonationChangeAmountDonorEmailJob.perform_later(recurring_donation, previous_amount)
+ RecurringDonationChangeAmountNonprofitEmailJob.perform_later(recurring_donation, previous_amount)
+ end
+end
diff --git a/app/jobs/recurring_donation_change_amount_nonprofit_email_job.rb b/app/jobs/recurring_donation_change_amount_nonprofit_email_job.rb
new file mode 100644
index 00000000..9039cb9d
--- /dev/null
+++ b/app/jobs/recurring_donation_change_amount_nonprofit_email_job.rb
@@ -0,0 +1,6 @@
+class RecurringDonationChangeAmountNonprofitEmailJob < EmailJob
+
+ def perform(recurring_donation, previous_amount)
+ DonationMailer.nonprofit_recurring_donation_change_amount(recurring_donation.id, previous_amount).deliver_now
+ end
+end
diff --git a/app/jobs/recurring_donations_export_create_job.rb b/app/jobs/recurring_donations_export_create_job.rb
new file mode 100644
index 00000000..d66558d2
--- /dev/null
+++ b/app/jobs/recurring_donations_export_create_job.rb
@@ -0,0 +1,7 @@
+class RecurringDonationsExportCreateJob < ApplicationJob
+ queue_as :default
+
+ def perform(*args)
+ ExportRecurringDonations.run_export(*args)
+ end
+end
diff --git a/app/jobs/refund_notification_donor_email_job.rb b/app/jobs/refund_notification_donor_email_job.rb
new file mode 100644
index 00000000..946eb462
--- /dev/null
+++ b/app/jobs/refund_notification_donor_email_job.rb
@@ -0,0 +1,6 @@
+class RefundNotificationDonorEmailJob < EmailJob
+
+ def perform(refund)
+ UserMailer.refund_receipt(refund).deliver_now
+ end
+end
diff --git a/app/jobs/refund_notification_job.rb b/app/jobs/refund_notification_job.rb
new file mode 100644
index 00000000..0c7632d0
--- /dev/null
+++ b/app/jobs/refund_notification_job.rb
@@ -0,0 +1,7 @@
+class RefundNotificationJob < EmailJob
+
+ def perform(refund)
+ RefundNotificationDonorEmailJob.perform_later(refund)
+ RefundNotificationNonprofitEmailJob.perform_later(refund)
+ end
+end
diff --git a/app/jobs/refund_notification_nonprofit_email_job.rb b/app/jobs/refund_notification_nonprofit_email_job.rb
new file mode 100644
index 00000000..bef576f1
--- /dev/null
+++ b/app/jobs/refund_notification_nonprofit_email_job.rb
@@ -0,0 +1,6 @@
+class RefundNotificationNonprofitEmailJob < EmailJob
+
+ def perform(refund)
+ NonprofitMailer.refund_notification(refund.id).deliver_now
+ end
+end
diff --git a/app/jobs/role_added_job.rb b/app/jobs/role_added_job.rb
new file mode 100644
index 00000000..1706e35a
--- /dev/null
+++ b/app/jobs/role_added_job.rb
@@ -0,0 +1,6 @@
+class RoleAddedJob < EmailJob
+
+ def perform(role)
+ NonprofitAdminMailer.existing_invite(role).deliver_now
+ end
+end
diff --git a/app/jobs/stripe_account_create_job.rb b/app/jobs/stripe_account_create_job.rb
new file mode 100644
index 00000000..a1e82be8
--- /dev/null
+++ b/app/jobs/stripe_account_create_job.rb
@@ -0,0 +1,6 @@
+class StripeAccountCreateJob < EmailJob
+
+ def perform(nonprofit)
+ NonprofitMailer.setup_verification(nonprofit.id).deliver_now
+ end
+end
diff --git a/app/jobs/supporter_fundraiser_create_job.rb b/app/jobs/supporter_fundraiser_create_job.rb
new file mode 100644
index 00000000..262f277f
--- /dev/null
+++ b/app/jobs/supporter_fundraiser_create_job.rb
@@ -0,0 +1,7 @@
+class SupporterFundraiserCreateJob < ApplicationJob
+ queue_as :default
+
+ def perform(fundraiser)
+ NonprofitAdminMailer.supporter_fundraiser(fundraiser).deliver_now unless QueryRoles.is_nonprofit_user?(fundraiser.profile.user.id, fundraiser.nonprofit.id)
+ end
+end
diff --git a/app/jobs/supporter_notes_export_create_job.rb b/app/jobs/supporter_notes_export_create_job.rb
new file mode 100644
index 00000000..c4594955
--- /dev/null
+++ b/app/jobs/supporter_notes_export_create_job.rb
@@ -0,0 +1,7 @@
+class SupporterNotesExportCreateJob < EmailJob
+ queue_as :default
+
+ def perform(npo_id, params, user_id, export_id)
+ ExportSupporterNotes.run_export(npo_id, params, user_id, export_id)
+ end
+end
diff --git a/app/jobs/supporters_export_create_job.rb b/app/jobs/supporters_export_create_job.rb
new file mode 100644
index 00000000..8ad1f1d5
--- /dev/null
+++ b/app/jobs/supporters_export_create_job.rb
@@ -0,0 +1,6 @@
+class SupportersExportCreateJob < EmailJob
+
+ def perform(*args)
+ ExportSupporters.run_export(*args)
+ end
+end
diff --git a/app/jobs/user_invite_create_job.rb b/app/jobs/user_invite_create_job.rb
new file mode 100644
index 00000000..243c4e62
--- /dev/null
+++ b/app/jobs/user_invite_create_job.rb
@@ -0,0 +1,6 @@
+class UserInviteCreateJob < EmailJob
+
+ def perform(role, raw_token)
+ NonprofitAdminMailer.new_invite(role, raw_token).deliver_now
+ end
+end
diff --git a/app/jobs/verification_completed_job.rb b/app/jobs/verification_completed_job.rb
new file mode 100644
index 00000000..7e939161
--- /dev/null
+++ b/app/jobs/verification_completed_job.rb
@@ -0,0 +1,6 @@
+class VerificationCompletedJob < EmailJob
+
+ def perform(nonprofit)
+ NonprofitMailer.successful_verification_notice(nonprofit).deliver_now
+ end
+end
diff --git a/app/jobs/verification_failed_job.rb b/app/jobs/verification_failed_job.rb
new file mode 100644
index 00000000..708af204
--- /dev/null
+++ b/app/jobs/verification_failed_job.rb
@@ -0,0 +1,6 @@
+class VerificationFailedJob < EmailJob
+
+ def perform(nonprofit)
+ NonprofitMailer.failed_verification_notice(onprofit).deliver_now
+ end
+end
diff --git a/app/jobs/we_move_execute_for_donations_job.rb b/app/jobs/we_move_execute_for_donations_job.rb
new file mode 100644
index 00000000..ce7cba77
--- /dev/null
+++ b/app/jobs/we_move_execute_for_donations_job.rb
@@ -0,0 +1,7 @@
+class WeMoveExecuteForDonationsJob < ApplicationJob
+ queue_as :default
+
+ def perform(donation)
+ QueueDonations.execute_for_donation(donation.id)
+ end
+end
diff --git a/app/listeners/application_listener.rb b/app/listeners/application_listener.rb
new file mode 100644
index 00000000..90820431
--- /dev/null
+++ b/app/listeners/application_listener.rb
@@ -0,0 +1,5 @@
+class ApplicationListener
+ def name
+ self.class.name
+ end
+end
diff --git a/app/listeners/campaign_listener.rb b/app/listeners/campaign_listener.rb
new file mode 100644
index 00000000..f8129080
--- /dev/null
+++ b/app/listeners/campaign_listener.rb
@@ -0,0 +1,11 @@
+class CampaignListener < ApplicationListener
+ def campaign_create(campaign)
+ if campaign.child_campaign?
+ CampaignCreationFederatedEmailJob.perform_later(campaign)
+ else
+ CampaignCreationEmailFollowupJob.perform_later(campaign)
+ end
+
+ SupporterFundraiserCreateJob.perform_later(campaign)
+ end
+end
diff --git a/app/listeners/credit_card_payment_listener.rb b/app/listeners/credit_card_payment_listener.rb
new file mode 100644
index 00000000..61129c08
--- /dev/null
+++ b/app/listeners/credit_card_payment_listener.rb
@@ -0,0 +1,33 @@
+class CreditCardPaymentListener < ApplicationListener
+ def donation_create(donation, locale, user=nil)
+ if donation.payment_provider == :credit_card
+ PaymentNotificationEmailDonorJob.perform_later donation, locale
+ PaymentNotificationEmailNonprofitJob.perform_later donation, user
+ end
+ end
+
+ def recurring_donation_create(donation, locale, user=nil)
+ if donation.payment_provider == :credit_card
+ PaymentNotificationEmailDonorJob.perform_later donation, locale
+ PaymentNotificationEmailNonprofitJob.perform_later donation, user
+ end
+ end
+
+ def refund_create(refund)
+ RefundNotificationJob.perform_later refund
+ end
+
+ def recurring_donation_payment_succeeded(donation, locale, user=nil)
+ if donation.payment_provider == :credit_card
+ PaymentNotificationEmailDonorJob.perform_later donation, locale
+ PaymentNotificationEmailNonprofitJob.perform_later donation, user
+ end
+ end
+
+ def recurring_donation_payment_failed(donation, locale)
+ FailedRecurringDonationPaymentDonorEmailJob.perform_later(donation)
+ if (donation.recurring_donation.n_failures >= 3)
+ FailedRecurringDonationPaymentNonprofitEmailJob.perform_later(donation)
+ end
+ end
+end
diff --git a/app/listeners/nonprofit_mailer_listener.rb b/app/listeners/nonprofit_mailer_listener.rb
new file mode 100644
index 00000000..3cc2edcf
--- /dev/null
+++ b/app/listeners/nonprofit_mailer_listener.rb
@@ -0,0 +1,5 @@
+class NonprofitMailerListener < ApplicationListener
+ def nonprofit_create(nonprofit)
+
+ end
+end
\ No newline at end of file
diff --git a/app/listeners/sepa_payment_listener.rb b/app/listeners/sepa_payment_listener.rb
new file mode 100644
index 00000000..67a00ab6
--- /dev/null
+++ b/app/listeners/sepa_payment_listener.rb
@@ -0,0 +1,8 @@
+class SepaPaymentListener < ApplicationListener
+ def donation_create(donation)
+ if donation.payment_provider == :sepa
+ DirectDebitCreateNotifyNonprofitJob.perform_later(donation.id)
+ DirectDebitCreateNotifyDonorJob.perform_later donation.id, locale
+ end
+ end
+end
diff --git a/app/listeners/ticket_listener.rb b/app/listeners/ticket_listener.rb
new file mode 100644
index 00000000..6cac8f0a
--- /dev/null
+++ b/app/listeners/ticket_listener.rb
@@ -0,0 +1,6 @@
+class TicketListener < ApplicationListener
+ def ticket_create(tickets, charge, user=nil)
+ TicketMailer.followup(tickets.map{|i| i.id}, charge && charge.id).deliver_later
+ TicketMailer.receipt_admin(tickets.map{|i| i.id}, user && user.id).deliver_later
+ end
+end
\ No newline at end of file
diff --git a/app/listeners/wemove_listener.rb b/app/listeners/wemove_listener.rb
new file mode 100644
index 00000000..cbc5d3f3
--- /dev/null
+++ b/app/listeners/wemove_listener.rb
@@ -0,0 +1,13 @@
+class WemoveListener < ApplicationListener
+ def donation_create(donation)
+ WeMoveExecuteForDonationsJob.perform_later(donation)
+ end
+
+ def offsite_donation_create(donation)
+ WeMoveExecuteForDonationsJob.perform_later(donation)
+ end
+
+ def recurring_donation_create(donation)
+ WeMoveExecuteForDonationsJob.perform_later(donation)
+ end
+end
diff --git a/app/mailers/admin_mailer.rb b/app/mailers/admin_mailer.rb
index 11e5250b..1699f1b3 100644
--- a/app/mailers/admin_mailer.rb
+++ b/app/mailers/admin_mailer.rb
@@ -1,6 +1,7 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
class AdminMailer < BaseMailer
-
# Subject can be set in your I18n file at config/locales/en.yml
# with the following lookup:
#
diff --git a/app/mailers/base_mailer.rb b/app/mailers/base_mailer.rb
index 95021647..605976a3 100644
--- a/app/mailers/base_mailer.rb
+++ b/app/mailers/base_mailer.rb
@@ -1,8 +1,10 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
class BaseMailer < ActionMailer::Base
include Roadie::Rails::Automatic
include Devise::Controllers::UrlHelpers
add_template_helper(ApplicationHelper)
- default :from => Settings.mailer.default_from
+ default from: Settings.mailer.default_from
layout 'email'
end
diff --git a/app/mailers/billing_subscription_mailer.rb b/app/mailers/billing_subscription_mailer.rb
index 93240743..971f4dbd 100644
--- a/app/mailers/billing_subscription_mailer.rb
+++ b/app/mailers/billing_subscription_mailer.rb
@@ -1,13 +1,13 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
class BillingSubscriptionMailer < BaseMailer
-
def failed_notice(np_id)
@nonprofit = Nonprofit.find(np_id)
@billing_subscription = @nonprofit.billing_subscription
@card = @nonprofit.active_card
@billing_plan = @billing_subscription.billing_plan
- @emails = QueryUsers.all_nonprofit_user_emails(@nonprofit.id)
- mail(to: @emails, subject: "Action Needed, Please Update Your #{Settings.general.name} Account")
+ @emails = QueryUsers.all_nonprofit_user_emails(@nonprofit.id)
+ mail(to: @emails, subject: "Action Needed, Please Update Your #{Settings.general.name} Account")
end
-
end
diff --git a/app/mailers/campaign_mailer.rb b/app/mailers/campaign_mailer.rb
index 6919bef2..72fcb0ae 100644
--- a/app/mailers/campaign_mailer.rb
+++ b/app/mailers/campaign_mailer.rb
@@ -1,15 +1,16 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
class CampaignMailer < BaseMailer
+ def creation_followup(campaign)
+ @creator_profile = campaign.profile
+ @campaign = campaign
+ mail(to: @creator_profile.user.email, subject: "Get your new campaign rolling! (via #{Settings.general.name})")
+ end
- def creation_followup(campaign)
- @creator_profile = campaign.profile
- @campaign = campaign
- mail(:to => @creator_profile.user.email, :subject => "Get your new campaign rolling! (via #{Settings.general.name})")
- end
-
- def federated_creation_followup(campaign)
- @creator_profile = campaign.profile
- @campaign = campaign
- mail(:to => @creator_profile.user.email, :subject => "Get your new campaign rolling! (via #{Settings.general.name})")
- end
+ def federated_creation_followup(campaign)
+ @creator_profile = campaign.profile
+ @campaign = campaign
+ mail(to: @creator_profile.user.email, subject: "Get your new campaign rolling! (via #{Settings.general.name})")
+ end
end
diff --git a/app/mailers/donation_mailer.rb b/app/mailers/donation_mailer.rb
index 35daa7f2..d86a54bf 100644
--- a/app/mailers/donation_mailer.rb
+++ b/app/mailers/donation_mailer.rb
@@ -1,36 +1,38 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
class DonationMailer < BaseMailer
-
- # Used for both one-time and recurring donations
+ # Used for both one-time and recurring donations
# can pass in array of admin user_ids to send to only some -- if falsey/empty, will send to all
- def donor_payment_notification(donation_id, locale=I18n.locale)
- @donation = Donation.find(donation_id)
- @nonprofit = @donation.nonprofit
- if @donation.campaign && ActionView::Base.full_sanitizer.sanitize(@donation.campaign.receipt_message).present?
+ def donor_payment_notification(donation_id, locale = I18n.locale)
+ @donation = Donation.find(donation_id)
+ @nonprofit = @donation.nonprofit
+ if @donation.campaign && ActionView::Base.full_sanitizer.sanitize(@donation.campaign.receipt_message).present?
@thank_you_note = @donation.campaign.receipt_message
else
- @thank_you_note = Format::Interpolate.with_hash(@nonprofit.thank_you_note, {'NAME' => @donation.supporter.name})
+ @thank_you_note = Format::Interpolate.with_hash(@nonprofit.thank_you_note, 'NAME' => @donation.supporter.name)
end
@charge = @donation.charges.last
- reply_to = @nonprofit.email.blank? ? @nonprofit.users.first.email : @nonprofit.email
+ reply_to = @nonprofit.email.blank? ? @nonprofit.users.first.email : @nonprofit.email
from = Format::Name.email_from_np(@nonprofit.name)
I18n.with_locale(locale) do
- mail(
- to: @donation.supporter.email,
- from: from,
- reply_to: reply_to,
- subject: I18n.t('mailer.donations.donor_direct_debit_notification.subject', nonprofit_name: @nonprofit.name))
+ mail(
+ to: @donation.supporter.email,
+ from: from,
+ reply_to: reply_to,
+ subject: I18n.t('mailer.donations.donor_direct_debit_notification.subject', nonprofit_name: @nonprofit.name)
+ )
end
end
- def donor_direct_debit_notification(donation_id, locale=I18n.locale)
+ def donor_direct_debit_notification(donation_id, locale = I18n.locale)
@donation = Donation.find(donation_id)
@nonprofit = @donation.nonprofit
- if @donation.campaign && ActionView::Base.full_sanitizer.sanitize(@donation.campaign.receipt_message).present?
+ if @donation.campaign && ActionView::Base.full_sanitizer.sanitize(@donation.campaign.receipt_message).present?
@thank_you_note = @donation.campaign.receipt_message
else
- @thank_you_note = Format::Interpolate.with_hash(@nonprofit.thank_you_note, {'NAME' => @donation.supporter.name})
+ @thank_you_note = Format::Interpolate.with_hash(@nonprofit.thank_you_note, 'NAME' => @donation.supporter.name)
end
reply_to = @nonprofit.email.blank? ? @nonprofit.users.first.email : @nonprofit.email
@@ -45,87 +47,86 @@ class DonationMailer < BaseMailer
end
end
- # Used for both one-time and recurring donations
- def nonprofit_payment_notification(donation_id, user_id=nil)
- @donation = Donation.find(donation_id)
- @charge = @donation.charges.last
- @nonprofit = @donation.nonprofit
+ # Used for both one-time and recurring donations
+ def nonprofit_payment_notification(donation_id, user_id = nil)
+ @donation = Donation.find(donation_id)
+ @charge = @donation.charges.last
+ @nonprofit = @donation.nonprofit
@emails = QueryUsers.nonprofit_user_emails(@nonprofit.id, @donation.campaign ? 'notify_campaigns' : 'notify_payments')
if user_id
em = User.find(user_id).email
# return unless @emails.include?(em)
@emails = [em]
end
- mail(to: @emails, subject: "Donation receipt for #{@donation.supporter.name}")
- end
+ mail(to: @emails, subject: "Donation receipt for #{@donation.supporter.name}")
+ end
def nonprofit_failed_recurring_donation(donation_id)
- @donation = Donation.find(donation_id)
- @nonprofit = @donation.nonprofit
- @charge = @donation.charges.last
+ @donation = Donation.find(donation_id)
+ @nonprofit = @donation.nonprofit
+ @charge = @donation.charges.last
@emails = QueryUsers.nonprofit_user_emails(@nonprofit.id, @donation.campaign ? 'notify_campaigns' : 'notify_payments')
- mail(to: @emails, subject: "Recurring donation payment failure for #{@donation.supporter.name || @donation.supporter.email}")
+ mail(to: @emails, subject: "Recurring donation payment failure for #{@donation.supporter.name || @donation.supporter.email}")
end
def donor_failed_recurring_donation(donation_id)
- @donation = Donation.find(donation_id)
- @nonprofit = @donation.nonprofit
- @charge = @donation.charges.last
- reply_to = @nonprofit.email.blank? ? @nonprofit.users.first.email : @nonprofit.email
+ @donation = Donation.find(donation_id)
+ @nonprofit = @donation.nonprofit
+ @charge = @donation.charges.last
+ reply_to = @nonprofit.email.blank? ? @nonprofit.users.first.email : @nonprofit.email
from = Format::Name.email_from_np(@nonprofit.name)
- mail(to: @donation.supporter.email, from: from, reply_to: reply_to, subject: "Donation payment failure for #{@nonprofit.name}")
+ mail(to: @donation.supporter.email, from: from, reply_to: reply_to, subject: "Donation payment failure for #{@nonprofit.name}")
end
def nonprofit_recurring_donation_cancellation(donation_id)
- @donation = Donation.find(donation_id)
- @nonprofit = @donation.nonprofit
- @charge = @donation.charges.last
+ @donation = Donation.find(donation_id)
+ @nonprofit = @donation.nonprofit
+ @charge = @donation.charges.last
@emails = QueryUsers.nonprofit_user_emails(@nonprofit.id, @donation.campaign ? 'notify_campaigns' : 'notify_payments')
- mail(to: @emails, subject: "Recurring donation cancelled for #{@donation.supporter.name || @donation.supporter.email}")
- end
+ mail(to: @emails, subject: "Recurring donation cancelled for #{@donation.supporter.name || @donation.supporter.email}")
+ end
- def nonprofit_recurring_donation_change_amount(donation_id, previous_amount=nil)
- @donation = RecurringDonation.find(donation_id).donation
- @nonprofit = @donation.nonprofit
- @emails = QueryUsers.nonprofit_user_emails(@nonprofit.id, 'notify_recurring_donations')
- @previous_amount = previous_amount
- mail(to: @emails, subject:"Recurring donation amount changed for #{@donation.supporter.name || @donation.supporter.email}")
- end
+ def nonprofit_recurring_donation_change_amount(donation_id, previous_amount = nil)
+ @donation = RecurringDonation.find(donation_id).donation
+ @nonprofit = @donation.nonprofit
+ @emails = QueryUsers.nonprofit_user_emails(@nonprofit.id, 'notify_recurring_donations')
+ @previous_amount = previous_amount
+ mail(to: @emails, subject: "Recurring donation amount changed for #{@donation.supporter.name || @donation.supporter.email}")
+ end
- def donor_recurring_donation_change_amount(donation_id, previous_amount=nil)
- @donation = RecurringDonation.find(donation_id).donation
- @nonprofit = @donation.nonprofit
- reply_to = @nonprofit.email.blank? ? @nonprofit.users.first.email : @nonprofit.email
- if @nonprofit.miscellaneous_np_info && ActionView::Base.full_sanitizer.sanitize(@nonprofit.miscellaneous_np_info.change_amount_message).present?
- @thank_you_note = @nonprofit.miscellaneous_np_info.change_amount_message
- else
- @thank_you_note = nil
- end
- from = Format::Name.email_from_np(@nonprofit.name)
- @previous_amount = previous_amount
- mail(to: @donation.supporter.email, from: from, reply_to: reply_to, subject: "Recurring donation amount changed for #{@nonprofit.name}")
- end
+ def donor_recurring_donation_change_amount(donation_id, previous_amount = nil)
+ @donation = RecurringDonation.find(donation_id).donation
+ @nonprofit = @donation.nonprofit
+ reply_to = @nonprofit.email.blank? ? @nonprofit.users.first.email : @nonprofit.email
+ if @nonprofit.miscellaneous_np_info && ActionView::Base.full_sanitizer.sanitize(@nonprofit.miscellaneous_np_info.change_amount_message).present?
+ @thank_you_note = @nonprofit.miscellaneous_np_info.change_amount_message
+ else
+ @thank_you_note = nil
+ end
+ from = Format::Name.email_from_np(@nonprofit.name)
+ @previous_amount = previous_amount
+ mail(to: @donation.supporter.email, from: from, reply_to: reply_to, subject: "Recurring donation amount changed for #{@nonprofit.name}")
+ end
- def nonprofit_recurring_donation_change_amount(donation_id, previous_amount=nil)
- @donation = RecurringDonation.find(donation_id).donation
- @nonprofit = @donation.nonprofit
- @emails = QueryUsers.nonprofit_user_emails(@nonprofit.id, 'notify_recurring_donations')
- @previous_amount = previous_amount
- mail(to: @emails, subject:"Recurring donation amount changed for #{@donation.supporter.name || @donation.supporter.email}")
- end
-
- def donor_recurring_donation_change_amount(donation_id, previous_amount=nil)
- @donation = RecurringDonation.find(donation_id).donation
- @nonprofit = @donation.nonprofit
- reply_to = @nonprofit.email.blank? ? @nonprofit.users.first.email : @nonprofit.email
- if @nonprofit.miscellaneous_np_info && ActionView::Base.full_sanitizer.sanitize(@nonprofit.miscellaneous_np_info.change_amount_message).present?
- @thank_you_note = @nonprofit.miscellaneous_np_info.change_amount_message
- else
- @thank_you_note = nil
- end
- from = Format::Name.email_from_np(@nonprofit.name)
- @previous_amount = previous_amount
- mail(to: @donation.supporter.email, from: from, reply_to: reply_to, subject: "Recurring donation amount changed for #{@nonprofit.name}")
- end
+ def nonprofit_recurring_donation_change_amount(donation_id, previous_amount = nil)
+ @donation = RecurringDonation.find(donation_id).donation
+ @nonprofit = @donation.nonprofit
+ @emails = QueryUsers.nonprofit_user_emails(@nonprofit.id, 'notify_recurring_donations')
+ @previous_amount = previous_amount
+ mail(to: @emails, subject: "Recurring donation amount changed for #{@donation.supporter.name || @donation.supporter.email}")
+ end
+ def donor_recurring_donation_change_amount(donation_id, previous_amount = nil)
+ @donation = RecurringDonation.find(donation_id).donation
+ @nonprofit = @donation.nonprofit
+ reply_to = @nonprofit.email.blank? ? @nonprofit.users.first.email : @nonprofit.email
+ if @nonprofit.miscellaneous_np_info && ActionView::Base.full_sanitizer.sanitize(@nonprofit.miscellaneous_np_info.change_amount_message).present?
+ @thank_you_note = @nonprofit.miscellaneous_np_info.change_amount_message
+ else
+ @thank_you_note = nil
+ end
+ from = Format::Name.email_from_np(@nonprofit.name)
+ @previous_amount = previous_amount
+ mail(to: @donation.supporter.email, from: from, reply_to: reply_to, subject: "Recurring donation amount changed for #{@nonprofit.name}")
+ end
end
diff --git a/app/mailers/event_mailer.rb b/app/mailers/event_mailer.rb
index 49a32b63..47f5ba2f 100644
--- a/app/mailers/event_mailer.rb
+++ b/app/mailers/event_mailer.rb
@@ -1,14 +1,14 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
class EventMailer < BaseMailer
+ helper :application
- helper :application
-
- include Devise::Controllers::UrlHelpers
-
- def creation_followup(event)
- @creator_profile = event.profile
- @event = event
- mail(:to => @creator_profile.user.email, :subject => "Get your new event rolling on #{Settings.general.name}!")
- end
+ include Devise::Controllers::UrlHelpers
+ def creation_followup(event)
+ @creator_profile = event.profile
+ @event = event
+ mail(to: @creator_profile.user.email, subject: "Get your new event rolling on #{Settings.general.name}!")
+ end
end
diff --git a/app/mailers/export_mailer.rb b/app/mailers/export_mailer.rb
index 2df3d36f..477eabf1 100644
--- a/app/mailers/export_mailer.rb
+++ b/app/mailers/export_mailer.rb
@@ -1,6 +1,7 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
class ExportMailer < BaseMailer
-
# Subject can be set in your I18n file at config/locales/en.yml
# with the following lookup:
#
@@ -18,7 +19,6 @@ class ExportMailer < BaseMailer
mail(to: @export.user.email, subject: 'Your payment export has failed')
end
-
def export_recurring_donations_completed_notification(export)
@export = export
diff --git a/app/mailers/generic_mailer.rb b/app/mailers/generic_mailer.rb
index 966c5f9e..c540e55a 100644
--- a/app/mailers/generic_mailer.rb
+++ b/app/mailers/generic_mailer.rb
@@ -1,11 +1,12 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
class GenericMailer < BaseMailer
-
- def generic_mail(from_email, from_name, message, subject, to_email, to_name)
+ def generic_mail(from_email, from_name, message, subject, to_email, _to_name)
@from_email = from_email
@from_name = from_name
@message = message
- mail(:to => to_email, :from => "#{from_name} <#{Settings.mailer.email}>", :reply_to => from_email, :subject => "#{subject}")
+ mail(to: to_email, from: "#{from_name} <#{Settings.mailer.email}>", reply_to: from_email, subject: subject.to_s)
end
# For sending a system notice to super admins
@@ -16,5 +17,4 @@ class GenericMailer < BaseMailer
emails = QueryUsers.super_admin_emails
mail(to: emails, from: "#{@from_name} <#{@from_email}>", reply_to: @from_email, subject: options[:subject], template_name: 'generic_mail')
end
-
end
diff --git a/app/mailers/import_mailer.rb b/app/mailers/import_mailer.rb
index 92a126f1..3adb30d0 100644
--- a/app/mailers/import_mailer.rb
+++ b/app/mailers/import_mailer.rb
@@ -1,10 +1,10 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
class ImportMailer < BaseMailer
-
- def import_completed_notification(import_id)
- @import = Import.find(import_id)
- @nonprofit = @import.nonprofit
- mail(to: @import.user.email, subject: "Your import is complete!")
- end
-
+ def import_completed_notification(import_id)
+ @import = Import.find(import_id)
+ @nonprofit = @import.nonprofit
+ mail(to: @import.user.email, subject: 'Your import is complete!')
+ end
end
diff --git a/app/mailers/nonprofit_admin_mailer.rb b/app/mailers/nonprofit_admin_mailer.rb
index f7cad1bb..b0198d38 100644
--- a/app/mailers/nonprofit_admin_mailer.rb
+++ b/app/mailers/nonprofit_admin_mailer.rb
@@ -1,28 +1,28 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
class NonprofitAdminMailer < BaseMailer
+ def new_invite(role, raw_token)
+ @user = role.user
+ @title_with_article = Format::Indefinitize.with_article(role.name.to_s.titleize)
+ @nonprofit = role.host
+ @token = raw_token
+ mail(to: @user.email, subject: "You're now #{@title_with_article} of #{@nonprofit.name} on #{Settings.general.name}. Let's set your password.")
+ end
- def new_invite(role, raw_token)
- @user = role.user
- @title_with_article = Format::Indefinitize.with_article(role.name.to_s.titleize)
- @nonprofit = role.host
- @token = raw_token
- mail(:to => @user.email, :subject => "You're now #{@title_with_article} of #{@nonprofit.name} on #{Settings.general.name}. Let's set your password.")
- end
+ def existing_invite(role)
+ @user = role.user
+ @title_with_article = Format::Indefinitize.with_article(role.name.to_s.titleize)
+ @nonprofit = role.host
+ mail(to: @user.email, subject: "You're now #{@title_with_article} of #{@nonprofit.name} on #{Settings.general.name}.")
+ end
- def existing_invite(role)
- @user = role.user
- @title_with_article = Format::Indefinitize.with_article(role.name.to_s.titleize)
- @nonprofit = role.host
- mail(:to => @user.email, :subject => "You're now #{@title_with_article} of #{@nonprofit.name} on #{Settings.general.name}.")
- end
-
- def supporter_fundraiser(event_or_campaign)
- @fundraiser = event_or_campaign
- @kind = event_or_campaign.class.name.downcase || 'event'
- @nonprofit = event_or_campaign.nonprofit
- @profile = event_or_campaign.profile
- recipients = @nonprofit.nonprofit_personnel_emails
- mail(to: recipients, subject: "A Supporter has created #{Format::Indefinitize.with_article(@kind.capitalize)} for your Nonprofit!")
- end
+ def supporter_fundraiser(event_or_campaign)
+ @fundraiser = event_or_campaign
+ @kind = event_or_campaign.class.name.downcase || 'event'
+ @nonprofit = event_or_campaign.nonprofit
+ @profile = event_or_campaign.profile
+ recipients = @nonprofit.nonprofit_personnel_emails
+ mail(to: recipients, subject: "A Supporter has created #{Format::Indefinitize.with_article(@kind.capitalize)} for your Nonprofit!")
+ end
end
-
diff --git a/app/mailers/nonprofit_mailer.rb b/app/mailers/nonprofit_mailer.rb
index e57bd62d..445c7b9e 100644
--- a/app/mailers/nonprofit_mailer.rb
+++ b/app/mailers/nonprofit_mailer.rb
@@ -1,6 +1,7 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
class NonprofitMailer < BaseMailer
-
def failed_verification_notice(np)
@nonprofit = np
@emails = QueryUsers.nonprofit_user_emails(@nonprofit.id, 'notify_payouts')
@@ -13,92 +14,93 @@ class NonprofitMailer < BaseMailer
mail(to: @emails, subject: "Verification successful on #{Settings.general.name}!")
end
- def refund_notification(refund_id)
- @refund = Refund.find(refund_id)
- @charge = @refund.charge
- @nonprofit = @refund.payment.nonprofit
+ def refund_notification(refund_id)
+ @refund = Refund.find(refund_id)
+ @charge = @refund.charge
+ @nonprofit = @refund.payment.nonprofit
@supporter = @refund.payment.supporter
- @emails = QueryUsers.nonprofit_user_emails(@nonprofit.id, 'notify_payments')
- mail(to: @emails, subject: "A new refund has been made for $#{Format::Currency.cents_to_dollars(@refund.amount)}")
- end
+ @emails = QueryUsers.nonprofit_user_emails(@nonprofit.id, 'notify_payments')
+ mail(to: @emails, subject: "A new refund has been made for $#{Format::Currency.cents_to_dollars(@refund.amount)}")
+ end
- def new_bank_account_notification(ba)
- @nonprofit = ba.nonprofit
- @bank_account = ba
- @emails = QueryUsers.all_nonprofit_user_emails(@nonprofit.id)
- mail(to: @emails, subject: "We need to confirm the new bank account")
- end
+ def new_bank_account_notification(ba)
+ @nonprofit = ba.nonprofit
+ @bank_account = ba
+ @emails = QueryUsers.all_nonprofit_user_emails(@nonprofit.id)
+ mail(to: @emails, subject: 'We need to confirm the new bank account')
+ end
- def pending_payout_notification(payout_id)
- @payout = Payout.find(payout_id)
- @nonprofit = @payout.nonprofit
- @emails = QueryUsers.nonprofit_user_emails(@nonprofit.id, 'notify_payouts')
- mail(to: @emails, subject: "Payout of available balance now pending")
- end
+ def pending_payout_notification(payout_id)
+ @payout = Payout.find(payout_id)
+ @nonprofit = @payout.nonprofit
+ @emails = QueryUsers.nonprofit_user_emails(@nonprofit.id, 'notify_payouts')
+ mail(to: @emails, subject: 'Payout of available balance now pending')
+ end
- def successful_payout_notification(payout)
- @nonprofit = payout.nonprofit
- @payout = payout
- @emails = QueryUsers.nonprofit_user_emails(@nonprofit.id, 'notify_payouts')
- mail(to: @emails, subject: "Payout of available balance succeeded")
- end
+ def successful_payout_notification(payout)
+ @nonprofit = payout.nonprofit
+ @payout = payout
+ @emails = QueryUsers.nonprofit_user_emails(@nonprofit.id, 'notify_payouts')
+ mail(to: @emails, subject: 'Payout of available balance succeeded')
+ end
- def failed_payout_notification(payout)
- @nonprofit = payout.nonprofit
- @payout = payout
- @emails = QueryUsers.nonprofit_user_emails(@nonprofit.id, 'notify_payouts')
- mail(to: @emails, subject: "Payout could not be completed")
- end
+ def failed_payout_notification(payout)
+ @nonprofit = payout.nonprofit
+ @payout = payout
+ @emails = QueryUsers.nonprofit_user_emails(@nonprofit.id, 'notify_payouts')
+ mail(to: @emails, subject: 'Payout could not be completed')
+ end
- def failed_recurring_donation(recurring_donation)
- @recurring_donation = recurring_donation
- @nonprofit = recurring_donation.nonprofit
- @emails = QueryUsers.nonprofit_user_emails(@nonprofit.id, 'notify_recurring_donations')
- mail(to: @emails, subject: "A recurring donation from one of your supporters had a payment failure.")
- end
+ def failed_recurring_donation(recurring_donation)
+ @recurring_donation = recurring_donation
+ @nonprofit = recurring_donation.nonprofit
+ @emails = QueryUsers.nonprofit_user_emails(@nonprofit.id, 'notify_recurring_donations')
+ mail(to: @emails, subject: 'A recurring donation from one of your supporters had a payment failure.')
+ end
- def cancelled_recurring_donation(recurring_donation)
- @recurring_donation = recurring_donation
- @nonprofit = recurring_donation.nonprofit
- @emails = QueryUsers.nonprofit_user_emails(@nonprofit.id, 'notify_recurring_donations')
- mail(to: @emails, subject: "A recurring donation from one of your supporters was cancelled.")
- end
+ def cancelled_recurring_donation(recurring_donation)
+ @recurring_donation = recurring_donation
+ @nonprofit = recurring_donation.nonprofit
+ @emails = QueryUsers.nonprofit_user_emails(@nonprofit.id, 'notify_recurring_donations')
+ mail(to: @emails, subject: 'A recurring donation from one of your supporters was cancelled.')
+ end
- def verified_notification(nonprofit)
- @nonprofit = nonprofit
- @emails = QueryUsers.all_nonprofit_user_emails(@nonprofit.id)
- mail(to: @emails, subject: "Your nonprofit has been verified!")
- end
+ def verified_notification(nonprofit)
+ @nonprofit = nonprofit
+ @emails = QueryUsers.all_nonprofit_user_emails(@nonprofit.id)
+ mail(to: @emails, subject: 'Your nonprofit has been verified!')
+ end
- def button_code(nonprofit, to_email, to_name, from_email, message, code)
- @nonprofit = nonprofit
- @to_email = to_email
- @to_name = to_name
- @from = from_email
- @message = message
- @code = code
+ def button_code(nonprofit, to_email, to_name, from_email, message, code)
+ @nonprofit = nonprofit
+ @to_email = to_email
+ @to_name = to_name
+ @from = from_email
+ @message = message
+ @code = code
from = Format::Name.email_from_np(@nonprofit.name)
- mail(to: to_email, from: from, reply_to: from_email, subject: "Please include this donate button code on the website")
- end
+ mail(to: to_email, from: from, reply_to: from_email, subject: 'Please include this donate button code on the website')
+ end
def invoice_payment_notification(nonprofit_id, payment)
@nonprofit = Nonprofit.find(nonprofit_id)
@payment = payment
@emails = QueryUsers.all_nonprofit_user_emails(@nonprofit.id, [:nonprofit_admin])
@month_name = Date::MONTHNAMES[payment.date.month]
- mail(to: @emails, subject: "#{Settings.general.name} Subscription Receipt for #{@month_name}")
+ mail(to: @emails, subject: "#{Settings.general.name} Subscription Receipt for #{@month_name}")
end
- # pass in all of:
- # {is_unsubscribed_from_emails, supporter_email, message, email_unsubscribe_uuid, nonprofit_id, from_email, subject}
- def supporter_message(args)
- return if args[:is_unsubscribed_from_emails] || args[:supporter_email].blank?
- @message = args[:message]
- @uuid = args[:email_unsubscribe_uuid]
- @nonprofit = Nonprofit.find args[:nonprofit_id]
+ # pass in all of:
+ # {is_unsubscribed_from_emails, supporter_email, message, email_unsubscribe_uuid, nonprofit_id, from_email, subject}
+ def supporter_message(args)
+ return if args[:is_unsubscribed_from_emails] || args[:supporter_email].blank?
+
+ @message = args[:message]
+ @uuid = args[:email_unsubscribe_uuid]
+ @nonprofit = Nonprofit.find args[:nonprofit_id]
from = Format::Name.email_from_np(@nonprofit.name)
- mail(to: args[:supporter_email], reply_to: args[:from_email], from: from, subject: args[:subject])
- end
+ mail(to: args[:supporter_email], reply_to: args[:from_email], from: from, subject: args[:subject])
+ end
def setup_verification(np_id)
@nonprofit = Nonprofit.find(np_id)
@@ -113,6 +115,4 @@ class NonprofitMailer < BaseMailer
@emails = QueryUsers.all_nonprofit_user_emails(np_id, [:nonprofit_admin])
mail(to: @emails, reply_to: 'support@commitchange.com', from: "#{Settings.general.name} Support", subject: "A hearty welcome from the #{Settings.general.name} team")
end
-
end
-
diff --git a/app/mailers/payment_mailer.rb b/app/mailers/payment_mailer.rb
index 28b7d52d..398477bf 100644
--- a/app/mailers/payment_mailer.rb
+++ b/app/mailers/payment_mailer.rb
@@ -1,14 +1,15 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
class PaymentMailer < BaseMailer
-
# Send a donation receipt to a single admin
# or a ticket receipt
def resend_admin_receipt(payment_id, user_id)
payment = Payment.find(payment_id)
if payment.kind == 'Donation' || payment.kind == 'RecurringDonation'
- return Delayed::Job.enqueue JobTypes::NonprofitPaymentNotificationJob.new(payment.donation.id, user_id)
+ PaymentNotificationEmailNonprofitJob.perform_later(payment.donation, User.find(user_id))
elsif payment.kind == 'Ticket'
- return TicketMailer.receipt_admin(payment.donation.id, user_id).deliver
+ return TicketMailer.receipt_admin(payment.donation.id, user_id).deliver_later
end
end
@@ -17,10 +18,9 @@ class PaymentMailer < BaseMailer
def resend_donor_receipt(payment_id)
payment = Payment.find(payment_id)
if payment.kind == 'Donation' || payment.kind == 'RecurringDonation'
- Delayed::Job.enqueue JobTypes::DonorPaymentNotificationJob.new(payment.donation.id)
+ PaymentNotificationEmailDonorJob.perform_later payment.donation
elsif payment.kind == 'Ticket'
- return TicketMailer.followup(payment.tickets.pluck(:id), payment.charge.id).deliver
+ return TicketMailer.followup(payment.tickets.pluck(:id), payment.charge).deliver_later
end
end
-
end
diff --git a/app/mailers/recurring_donation_mailer.rb b/app/mailers/recurring_donation_mailer.rb
index d1a4a649..ce64e58c 100644
--- a/app/mailers/recurring_donation_mailer.rb
+++ b/app/mailers/recurring_donation_mailer.rb
@@ -1,14 +1,15 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
class RecurringDonationMailer < BaseMailer
+ def send_cancellation_notices(recurring_donation)
+ UserMailer.recurring_donation_cancelled(recurring_donation).deliver
+ NonprofitMailer.cancelled_recurring_donation(recurring_donation).deliver
+ recurring_donation
+ end
- def send_cancellation_notices(recurring_donation)
- UserMailer.recurring_donation_cancelled(recurring_donation).deliver
- NonprofitMailer.cancelled_recurring_donation(recurring_donation).deliver
- return recurring_donation
- end
-
- def send_failure_notifications(recurring_donation)
- UserMailer.recurring_donation_failure(recurring_donation).deliver
- NonprofitMailer.failed_recurring_donation(recurring_donation).deliver
- end
+ def send_failure_notifications(recurring_donation)
+ UserMailer.recurring_donation_failure(recurring_donation).deliver
+ NonprofitMailer.failed_recurring_donation(recurring_donation).deliver
+ end
end
diff --git a/app/mailers/testing.rb b/app/mailers/testing.rb
index a82ab782..9d064245 100644
--- a/app/mailers/testing.rb
+++ b/app/mailers/testing.rb
@@ -1,4 +1,6 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
class Testing < ActionMailer::Base
- default from: "from@example.com"
+ default from: 'from@example.com'
end
diff --git a/app/mailers/ticket_mailer.rb b/app/mailers/ticket_mailer.rb
index 623646d6..7f39b499 100644
--- a/app/mailers/ticket_mailer.rb
+++ b/app/mailers/ticket_mailer.rb
@@ -1,22 +1,23 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
class TicketMailer < BaseMailer
-
helper :application
# Pass in ticket_ids, event_id, and supporter
- def followup(ticket_ids, charge_id=nil)
+ def followup(ticket_ids, charge_id = nil)
@charge = charge_id ? Charge.find(charge_id) : nil
- @tickets = Ticket.where("id IN(?)", ticket_ids)
+ @tickets = Ticket.where('id IN(?)', ticket_ids)
@event = @tickets.last.event
@supporter = @tickets.last.supporter
@nonprofit = @supporter.nonprofit
from = Format::Name.email_from_np(@nonprofit.name)
reply_to = @nonprofit.email.blank? ? @nonprofit.users.first.email : @nonprofit.email
- mail(from: from, to: @supporter.email, reply_to: reply_to, subject: "Your tickets#{@charge ? ' and receipt ' : ' '}for: #{@event.name}")
+ mail(from: from, to: @supporter.email, reply_to: reply_to, subject: "Your tickets#{@charge ? ' and receipt ' : ' '}for: #{@event.name}")
end
- def receipt_admin(ticket_ids, user_id=nil)
- @tickets = Ticket.where("id IN (?)", ticket_ids)
+ def receipt_admin(ticket_ids, user_id = nil)
+ @tickets = Ticket.where('id IN (?)', ticket_ids)
@charge = @tickets.last.charge
@supporter = @tickets.last.supporter
@event = @tickets.last.event
@@ -25,9 +26,9 @@ class TicketMailer < BaseMailer
if user_id
em = User.find(user_id).email
return unless recipients.include?(em)
+
recipients = [em]
end
mail(to: recipients, subject: "Ticket redeemed for #{@event.name} - #{@supporter.name}")
end
-
end
diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb
index f216cc0e..b9a01478 100644
--- a/app/mailers/user_mailer.rb
+++ b/app/mailers/user_mailer.rb
@@ -1,26 +1,26 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
class UserMailer < BaseMailer
-
- def refund_receipt(refund_id)
- @refund = Refund.find(refund_id)
+ def refund_receipt(refund_id)
+ @refund = Refund.find(refund_id)
@nonprofit = @refund.payment.nonprofit
- @charge = @refund.charge
+ @charge = @refund.charge
@supporter = @refund.payment.supporter
- reply_to = @nonprofit.email.blank? ? @nonprofit.users.first.email : @nonprofit.email
+ reply_to = @nonprofit.email.blank? ? @nonprofit.users.first.email : @nonprofit.email
from = Format::Name.email_from_np(@nonprofit.name)
- mail(to: @supporter.email, from: from, reply_to: reply_to, subject: "Your refund receipt for #{@nonprofit.name}")
- end
+ mail(to: @supporter.email, from: from, reply_to: reply_to, subject: "Your refund receipt for #{@nonprofit.name}")
+ end
- def recurring_donation_failure(recurring_donation)
- @recurring_donation = recurring_donation
- mail(:to => @recurring_donation.email,
- :subject => ("We couldn't process your recurring donation towards #{@recurring_donation.nonprofit.name}."))
- end
-
- def recurring_donation_cancelled(recurring_donation)
- @recurring_donation = recurring_donation
- mail(:to => @recurring_donation.email,
- :subject => ("Your recurring donation towards #{@recurring_donation.nonprofit.name} was successfully cancelled."))
- end
+ def recurring_donation_failure(recurring_donation)
+ @recurring_donation = recurring_donation
+ mail(to: @recurring_donation.email,
+ subject: "We couldn't process your recurring donation towards #{@recurring_donation.nonprofit.name}.")
+ end
+ def recurring_donation_cancelled(recurring_donation)
+ @recurring_donation = recurring_donation
+ mail(to: @recurring_donation.email,
+ subject: "Your recurring donation towards #{@recurring_donation.nonprofit.name} was successfully cancelled.")
+ end
end
diff --git a/app/models/activity.rb b/app/models/activity.rb
index c98f0888..8dd456c0 100644
--- a/app/models/activity.rb
+++ b/app/models/activity.rb
@@ -1,5 +1,5 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class Activity < ActiveRecord::Base
-
+class Activity < ApplicationRecord
end
-
diff --git a/app/models/application_record.rb b/app/models/application_record.rb
new file mode 100644
index 00000000..9f8f3f0d
--- /dev/null
+++ b/app/models/application_record.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
+
+class ApplicationRecord < ActiveRecord::Base
+ self.abstract_class = true
+end
diff --git a/app/models/bank_account.rb b/app/models/bank_account.rb
index 92265f4f..82291b55 100644
--- a/app/models/bank_account.rb
+++ b/app/models/bank_account.rb
@@ -1,41 +1,38 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class BankAccount < ActiveRecord::Base
+class BankAccount < ApplicationRecord
+ # :name, # str (readable bank name identifier, eg. "Wells Fargo *1234")
+ # :confirmation_token, # str (randomly generated private token for email confirmation)
+ # :account_number, # str (last digits only)
+ # :bank_name, # str
+ # :pending_verification, # bool (whether this bank account is still awaiting email confirmation)
+ # :status, # str
+ # :email, # str (contact email associated with the user who created this bank account)
+ # :deleted, # bool (soft delete flag)
+ # :stripe_bank_account_token, # str
+ # :stripe_bank_account_id, # str
+ # :nonprofit_id, :nonprofit
+ validates :stripe_bank_account_token, presence: true, uniqueness: true
+ validates :stripe_bank_account_id, presence: true, uniqueness: true
+ validates :nonprofit, presence: true
+ validates :email, presence: true, format: {with: Email::Regex}
+ validate :nonprofit_must_be_vetted, on: :create
+ validate :nonprofit_has_stripe_account
- attr_accessible \
- :name, # str (readable bank name identifier, eg. "Wells Fargo *1234")
- :confirmation_token, # str (randomly generated private token for email confirmation)
- :account_number, # str (last digits only)
- :bank_name, # str
- :pending_verification, # bool (whether this bank account is still awaiting email confirmation)
- :status, # str
- :email, # str (contact email associated with the user who created this bank account)
- :deleted, # bool (soft delete flag)
- :stripe_bank_account_token, # str
- :stripe_bank_account_id, # str
- :nonprofit_id, :nonprofit
+ has_many :payouts
+ belongs_to :nonprofit
- #validates :stripe_bank_account_token, presence: true, uniqueness: true
- # validates :stripe_bank_account_id, presence: true, uniqueness: true
- #validates :nonprofit, presence: true
- #validates :email, presence: true, format: {with: Email::Regex}
- #validate :nonprofit_must_be_vetted, on: :create
- #validate :nonprofit_has_stripe_account
+ def nonprofit_must_be_vetted
+ errors.add(:nonprofit, 'must be vetted') unless nonprofit&.vetted
+ end
- has_many :payouts
- belongs_to :nonprofit
-
- def nonprofit_must_be_vetted
- errors.add(:nonprofit, "must be vetted") unless self.nonprofit && self.nonprofit.vetted
- end
-
-
- def nonprofit_has_stripe_account
- errors.add(:nonprofit, 'must have a Stripe account id') if !self.nonprofit || self.nonprofit.stripe_account_id.blank?
- end
-
- # Manually cause an instance to become invalid
- def invalidate!
- @not_valid = true
- end
+ def nonprofit_has_stripe_account
+ errors.add(:nonprofit, 'must have a Stripe account id') if !nonprofit || nonprofit.stripe_account_id.blank?
+ end
+ # Manually cause an instance to become invalid
+ def invalidate!
+ @not_valid = true
+ end
end
diff --git a/app/models/base.rb b/app/models/base.rb
new file mode 100644
index 00000000..97737b0c
--- /dev/null
+++ b/app/models/base.rb
@@ -0,0 +1,41 @@
+
+
+class Base
+ include ActiveModel::Model
+ include ActiveModel::Validations
+ include ActiveModel::Validations::Callbacks
+
+
+ def self.validate_nested_attribute(*attributes)
+ validates_with NestedAttributesValidator, _merge_attributes(attributes)
+ end
+
+
+ private
+
+ def _merge_attributes(attr_names)
+ options = attr_names.extract_options!.symbolize_keys
+ attr_names.flatten!
+ options[:attributes] = attr_names
+ options
+ end
+
+ class NestedAttributesValidator < ActiveModel::EachValidator
+ def initialize(options)
+ @model_class = options[:model_class]
+ super
+ end
+
+ def validate_each(record, attribute, value)
+ inner_validator = @model_class.new(value) unless value.is_a? @model_class
+ return if inner_validator.valid?
+ add_nested_errors_for(record, attribute, inner_validator)
+ end
+
+ def add_nested_errors_for(record, attribute, other_validator)
+ record.errors.messages[attribute] = other_validator.errors.messages
+ record.errors.details[attribute] = other_validator.errors.details
+ end
+ end
+ end
+
diff --git a/app/models/billing_plan.rb b/app/models/billing_plan.rb
index 552a273d..5b671256 100644
--- a/app/models/billing_plan.rb
+++ b/app/models/billing_plan.rb
@@ -1,18 +1,19 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class BillingPlan < ActiveRecord::Base
- Names = ['Starter', 'Fundraising', 'Supporter Management']
- DefaultAmounts = [0, 9900, 29900] # in pennies
+class BillingPlan < ApplicationRecord
+ # :name, #str: readable name
+ # :tier, #int: 0-4 (0: Free, 1: Fundraising, 2: Supporter Management)
+ # :amount, #int (cents)
+ # :stripe_plan_id, #str (matches plan ID in Stripe) Not needed if it's not a paying subscription
+ # :interval, #str ('monthly', 'annual')
+ # :percentage_fee # 0.038
- attr_accessible \
- :name, #str: readable name
- :tier, #int: 0-4 (0: Free, 1: Fundraising, 2: Supporter Management)
- :amount, #int (cents)
- :stripe_plan_id, #str (matches plan ID in Stripe) Not needed if it's not a paying subscription
- :interval, #str ('monthly', 'annual')
- :percentage_fee # 0.038
+ Names = ['Starter', 'Fundraising', 'Supporter Management'].freeze
+ DefaultAmounts = [0, 9900, 29_900].freeze # in pennies
- has_many :billing_subscriptions
+ has_many :billing_subscriptions
- validates :name, :presence => true
- validates :amount, :presence => true
+ validates :name, presence: true
+ validates :amount, presence: true
end
diff --git a/app/models/billing_subscription.rb b/app/models/billing_subscription.rb
index 5e67bfea..f7f8831a 100644
--- a/app/models/billing_subscription.rb
+++ b/app/models/billing_subscription.rb
@@ -1,31 +1,29 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class BillingSubscription < ActiveRecord::Base
+class BillingSubscription < ApplicationRecord
+ # :nonprofit_id, :nonprofit,
+ # :billing_plan_id, :billing_plan,
+ # :stripe_subscription_id,
+ # :status # active, past_due, canceled, or unpaid
- attr_accessible \
- :nonprofit_id, :nonprofit,
- :billing_plan_id, :billing_plan,
- :stripe_subscription_id,
- :status # trialing, active, past_due, canceled, or unpaid
+ attr_accessor :stripe_plan_id, :manual
+ belongs_to :nonprofit
+ belongs_to :billing_plan
- attr_accessor :stripe_plan_id, :manual
- belongs_to :nonprofit
- belongs_to :billing_plan
+ validates :nonprofit, presence: true
+ validates :billing_plan, presence: true
- validates :nonprofit, presence: true
- validates :billing_plan, presence: true
-
- def as_json(options={})
- h = super(options)
- h[:plan_name] = self.billing_plan.name
- h[:plan_amount] = self.billing_plan.amount / 100
- h
- end
-
- def self.create_with_stripe(np, params)
- bp = BillingPlan.find_by_stripe_plan_id params[:stripe_plan_id]
- h = ConstructBillingSubscription.with_stripe np, bp
- return np.create_billing_subscription h
- end
+ def as_json(options = {})
+ h = super(options)
+ h[:plan_name] = billing_plan.name
+ h[:plan_amount] = billing_plan.amount / 100
+ h
+ end
+ def self.create_with_stripe(np, params)
+ bp = BillingPlan.find_by_stripe_plan_id params[:stripe_plan_id]
+ h = ConstructBillingSubscription.with_stripe np, bp
+ np.create_billing_subscription h
+ end
end
-
diff --git a/app/models/campaign.rb b/app/models/campaign.rb
index d4037873..fc2d3ed1 100644
--- a/app/models/campaign.rb
+++ b/app/models/campaign.rb
@@ -1,185 +1,184 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class Campaign < ActiveRecord::Base
+class Campaign < ApplicationRecord
+ include Image::AttachmentExtensions
+ # :name,
+ # :tagline,
+ # :slug, # str: url name
+ # :total_supporters,
+ # :goal_amount,
+ # :nonprofit_id,
+ # :profile_id,
+ # :main_image,
+ # :remove_main_image, # for carrierwave
+ # :background_image,
+ # :remove_background_image, #bool carrierwave
+ # :banner_image,
+ # :remove_banner_image,
+ # :published,
+ # :video_url, #str
+ # :vimeo_video_id,
+ # :youtube_video_id,
+ # :summary,
+ # :recurring_fund, # bool: whether this is a recurring campaign
+ # :body,
+ # :goal_amount_dollars, #accessor: translated into goal_amount (cents)
+ # :show_total_raised, # bool
+ # :show_total_count, # bool
+ # :hide_activity_feed, # bool
+ # :end_datetime,
+ # :deleted, #bool (soft delete)
+ # :hide_goal, # bool
+ # :hide_thermometer, #bool
+ # :hide_title, # bool
+ # :receipt_message, # text
+ # :hide_custom_amounts, # boolean
+ # :parent_campaign_id,
+ # :reason_for_supporting,
+ # :default_reason_for_supporting
- attr_accessible \
- :name,
- :tagline,
- :slug, # str: url name
- :total_supporters,
- :goal_amount,
- :nonprofit_id,
- :profile_id,
- :main_image,
- :remove_main_image, # for carrierwave
- :background_image,
- :remove_background_image, #bool carrierwave
- :banner_image,
- :remove_banner_image,
- :published,
- :video_url, #str
- :vimeo_video_id,
- :youtube_video_id,
- :summary,
- :recurring_fund, # bool: whether this is a recurring campaign
- :body,
- :goal_amount_dollars, #accessor: translated into goal_amount (cents)
- :show_total_raised, # bool
- :show_total_count, # bool
- :hide_activity_feed, # bool
- :end_datetime,
- :deleted, #bool (soft delete)
- :hide_goal, # bool
- :hide_thermometer, #bool
- :hide_title, # bool
- :receipt_message, # text
- :hide_custom_amounts, # boolean
- :parent_campaign_id,
- :reason_for_supporting,
- :default_reason_for_supporting
-
- validate :end_datetime_cannot_be_in_past, :on => :create
- validates :profile, :presence => true
- validates :nonprofit, :presence => true
- validates :goal_amount,
- :presence => true,
- :numericality => {:only_integer => true, :greater_than => 99}
- validates :name,
- :presence => true,
- :length => {:maximum => 60}
- validates :slug, uniqueness: {scope: :nonprofit_id, message: 'You already have a campaign with that URL.'}, presence: true
+ validate :end_datetime_cannot_be_in_past, on: :create
+ validates :profile, presence: true
+ validates :nonprofit, presence: true
+ validates :goal_amount,
+ presence: true,
+ numericality: { only_integer: true, greater_than: 99 }
+ validates :name,
+ presence: true,
+ length: { maximum: 60 }
+ validates :slug, uniqueness: { scope: :nonprofit_id, message: 'You already have a campaign with that URL.' }, presence: true
attr_accessor :goal_amount_dollars
- mount_uploader :main_image, CampaignMainImageUploader
- mount_uploader :background_image, CampaignBackgroundImageUploader
- mount_uploader :banner_image, CampaignBannerImageUploader
+ has_one_attached :main_image
+ has_one_attached :background_image
+ has_one_attached :banner_image
- has_many :donations
- has_many :charges, through: :donations
- has_many :payments, through: :donations
- has_many :campaign_gift_options
- has_many :campaign_gifts, through: :campaign_gift_options
- has_many :supporters, :through => :donations
- has_many :recurring_donations
- has_many :roles, as: :host, dependent: :destroy
- has_many :comments, as: :host, dependent: :destroy
- has_many :activities, as: :host, dependent: :destroy
- belongs_to :profile
- belongs_to :nonprofit
+ has_one_attached_with_sizes(:main_image, {normal: [524, 360], thumb: [180,150]})
+ has_one_attached_with_sizes(:background_image, {normal: [1000, 600]})
+
+ has_one_attached_with_default(:main_image, Image::DefaultProfileUrl,
+ filename: "main_image_#{SecureRandom.uuid}#{Pathname.new(Image::DefaultProfileUrl).extname}")
+
+ has_many :donations
+ has_many :charges, through: :donations
+ has_many :payments, through: :donations, source: 'payment'
+ has_many :campaign_gift_options
+ has_many :campaign_gifts, through: :campaign_gift_options
+ has_many :supporters, through: :donations
+ has_many :recurring_donations
+ has_many :roles, as: :host, dependent: :destroy
+ has_many :comments, as: :host, dependent: :destroy
+ has_many :activities, as: :host, dependent: :destroy
+ belongs_to :profile
+ belongs_to :nonprofit
belongs_to :parent_campaign, class_name: 'Campaign'
has_many :children_campaigns, class_name: 'Campaign', foreign_key: 'parent_campaign_id'
- scope :published, -> {where(:published => true)}
- scope :active, -> {where(:published => true).where("end_datetime IS NULL OR end_datetime >= ?", Date.today)}
- scope :past, -> {where(:published => true).where("end_datetime < ?", Date.today)}
- scope :unpublished, -> {where(:published => [nil, false])}
- scope :not_deleted, -> {where(deleted: [nil, false])}
- scope :deleted, -> {where(deleted: true)}
- scope :not_a_child, -> {where(parent_campaign_id: nil)}
+ scope :published, -> { where(published: true) }
+ scope :active, -> { where(published: true).where('end_datetime IS NULL OR end_datetime >= ?', Date.today) }
+ scope :past, -> { where(published: true).where('end_datetime < ?', Date.today) }
+ scope :unpublished, -> { where(published: [nil, false]) }
+ scope :not_deleted, -> { where(deleted: [nil, false]) }
+ scope :deleted, -> { where(deleted: true) }
+ scope :not_a_child, -> { where(parent_campaign_id: nil) }
- before_validation do
- if self.goal_amount_dollars.present?
- self.goal_amount = (self.goal_amount_dollars.gsub(',','').to_f * 100).to_i
- end
- self
- end
+ before_validation do
+ if goal_amount_dollars.present?
+ self.goal_amount = (goal_amount_dollars.delete(',').to_f * 100).to_i
+ end
+ self
+ end
- before_validation(on: :create) do
- unless self.slug
- self.slug = Format::Url.convert_to_slug(name)
- end
- self.set_defaults
- self
- end
+ before_validation(on: :create) do
+ self.slug = Format::Url.convert_to_slug(name) unless slug
+ set_defaults
+ self
+ end
- before_save do
- self.parse_video_id if self.video_url && self.video_url_changed?
- self
- end
+ before_save do
+ parse_video_id if video_url && video_url_changed?
+ self
+ end
- after_create do
- user = self.profile.user
- Role.create(name: :campaign_editor, user_id: user.id, host: self)
- if child_campaign?
- CampaignMailer.delay.federated_creation_followup(self)
- else
- CampaignMailer.delay.creation_followup(self)
- end
+ after_create do
+ user = profile.user
+ Role.create(name: :campaign_editor, user_id: user.id, host: self)
+ HoudiniEventPublisher.announce(:campaign_create, self)
+ self
+ end
- NonprofitAdminMailer.delay.supporter_fundraiser(self) unless QueryRoles.is_nonprofit_user?(user.id, self.nonprofit_id)
- self
- end
+ def set_defaults
+ self.total_supporters = 1
+ self.published = false if published.nil?
+ end
- def set_defaults
+ def parse_video_id
+ if video_url.include? 'vimeo'
+ self.vimeo_video_id = video_url.split('/').last
+ self.youtube_video_id = nil
+ elsif video_url.include? 'youtube'
+ match = video_url.match(/\?v=(.+)/)
+ return if match.nil?
- self.total_supporters = 1
- self.published = false if self.published.nil?
- end
+ self.youtube_video_id = match[1].split('&').first
+ self.vimeo_video_id = nil
+ elsif video_url.include? 'youtu.be'
+ self.youtube_video_id = video_url.split('/').last
+ self.vimeo_video_id = nil
+ elsif video_url.blank?
+ self.vimeo_video_id = nil
+ self.youtube_video_id = nil
+ end
+ self
+ end
+ def total_raised
+ payments.sum(:gross_amount)
+ end
- def parse_video_id
- if self.video_url.include? 'vimeo'
- self.vimeo_video_id = self.video_url.split('/').last
- self.youtube_video_id = nil
- elsif self.video_url.include? 'youtube'
- match = self.video_url.match(/\?v=(.+)/)
- return if match.nil?
- self.youtube_video_id = match[1].split('&').first
- self.vimeo_video_id = nil
- elsif self.video_url.include? 'youtu.be'
- self.youtube_video_id = self.video_url.split('/').last
- self.vimeo_video_id = nil
- elsif self.video_url.blank?
- self.vimeo_video_id = nil
- self.youtube_video_id = nil
- end
- self
- end
+ def percentage_funded
+ goal_amount.nil? ? 0 : total_raised * 100 / goal_amount
+ end
- def total_raised
- self.payments.sum(:gross_amount)
- end
+ def average_donation
+ donations.any? ? total_raised / donations.count : 0
+ end
- def percentage_funded
- self.goal_amount.nil? ? 0 : self.total_raised * 100 / self.goal_amount
- end
-
- def average_donation
- self.donations.any? ? self.total_raised / self.donations.count : 0
- end
-
- # Validations
+ # Validations
def end_datetime_cannot_be_in_past
- if self.end_datetime.present? && self.end_datetime < Time.now
+ if end_datetime.present? && end_datetime < Time.now
errors.add(:end_datetime, "can't be in the past")
- end
- end
+ end
+ end
- def ready_to_publish?
- [(self.body && self.body.length >= 500), (self.campaign_gift_options.count >= 1)].all?
- end
+ def ready_to_publish?
+ [(body && body.length >= 500), (campaign_gift_options.count >= 1)].all?
+ end
- def url
- "#{self.nonprofit.url}/campaigns/#{self.slug}"
- end
+ def url
+ "#{nonprofit.url}/campaigns/#{slug}"
+ end
- def days_left
- return 0 if self.end_datetime.nil?
- (self.end_datetime.to_date - Date.today).to_i
- end
+ def days_left
+ return 0 if end_datetime.nil?
- def finished?
- self.end_datetime && self.end_datetime < Time.now
- end
+ (end_datetime.to_date - Date.today).to_i
+ end
+
+ def finished?
+ end_datetime && end_datetime < Time.now
+ end
def child_params
- excluded_for_peer_to_peer = %w(
- id created_at updated_at slug profile_id url
+ excluded_for_peer_to_peer = %w[
+ id created_at updated_at slug profile_id url
total_raised show_recurring_amount external_identifier parent_campaign_id
reason_for_supporting metadata
- )
+ ]
attributes.except(*excluded_for_peer_to_peer)
end
diff --git a/app/models/campaign_gift.rb b/app/models/campaign_gift.rb
index be8e76ba..300d7b09 100644
--- a/app/models/campaign_gift.rb
+++ b/app/models/campaign_gift.rb
@@ -1,16 +1,15 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class CampaignGift < ActiveRecord::Base
+class CampaignGift < ApplicationRecord
+ # :donation_id,
+ # :donation,
+ # :campaign_gift_option,
+ # :campaign_gift_option_id
- attr_accessible \
- :donation_id,
- :donation,
- :campaign_gift_option,
- :campaign_gift_option_id
-
- belongs_to :donation
- belongs_to :campaign_gift_option
-
- validates :donation, presence: true
- validates :campaign_gift_option, presence: true
+ belongs_to :donation
+ belongs_to :campaign_gift_option
+ validates :donation, presence: true
+ validates :campaign_gift_option, presence: true
end
diff --git a/app/models/campaign_gift_option.rb b/app/models/campaign_gift_option.rb
index f69129c4..627c6298 100644
--- a/app/models/campaign_gift_option.rb
+++ b/app/models/campaign_gift_option.rb
@@ -1,35 +1,34 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class CampaignGiftOption < ActiveRecord::Base
+class CampaignGiftOption < ApplicationRecord
+ # :amount_one_time, #int (cents)
+ # :amount_recurring, #int (cents)
+ # :amount_dollars, #str, gets converted to amount
+ # :description, # text
+ # :name, # str
+ # :campaign, #assocation
+ # :quantity, #int (optional)
+ # :to_ship, #boolean
+ # :order, #int (optional)
+ # :hide_contributions #boolean (optional)
- attr_accessible \
- :amount_one_time, #int (cents)
- :amount_recurring, #int (cents)
- :amount_dollars, #str, gets converted to amount
- :description, # text
- :name, # str
- :campaign, #assocation
- :quantity, #int (optional)
- :to_ship, #boolean
- :order, #int (optional)
- :hide_contributions #boolean (optional)
+ belongs_to :campaign
+ has_many :campaign_gifts
+ has_many :donations, through: :campaign_gifts
- belongs_to :campaign
- has_many :campaign_gifts
- has_many :donations, through: :campaign_gifts
+ validates :name, presence: true
+ validates :campaign, presence: true
+ validates :amount_one_time, presence: true, numericality: { only_integer: true }, unless: :amount_recurring
+ validates :amount_recurring, presence: true, numericality: { only_integer: true }, unless: :amount_one_time
- validates :name, presence: true
- validates :campaign, presence: true
- validates :amount_one_time, presence: true, numericality: { only_integer: true }, unless: :amount_recurring
- validates :amount_recurring, presence: true, numericality: { only_integer: true }, unless: :amount_one_time
-
- def total_gifts
- return self.campaign_gifts.count
- end
-
- def as_json(options={})
- h = super(options)
- h[:total_gifts] = self.total_gifts
- h
- end
+ def total_gifts
+ campaign_gifts.count
+ end
+ def as_json(options = {})
+ h = super(options)
+ h[:total_gifts] = total_gifts
+ h
+ end
end
diff --git a/app/models/card.rb b/app/models/card.rb
index d7b806f8..4a1b92d0 100755
--- a/app/models/card.rb
+++ b/app/models/card.rb
@@ -1,25 +1,22 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class Card < ActiveRecord::Base
+class Card < ApplicationRecord
+ # :cardholders_name, # str (name associated with this card)
+ # :email, # str (cache the email associated with this card)
+ # :name, # str (readable card name, eg. Visa *1234)
+ # :failure_message, # accessor for temporarily storing the stripe decline message
+ # :status, # str
+ # :stripe_card_token, # str
+ # :stripe_card_id, # str
+ # :stripe_customer_id, # str
+ # :holder, :holder_id, :holder_type, # polymorphic cardholder association
+ # :inactive # a card is inactive. This is currently only meaningful for nonprofit cards
- attr_accessible \
- :cardholders_name, # str (name associated with this card)
- :email, # str (cache the email associated with this card)
- :name, # str (readable card name, eg. Visa *1234)
- :failure_message, # accessor for temporarily storing the stripe decline message
- :status, # str
- :stripe_card_token, # str
- :stripe_card_id, # str
- :stripe_customer_id, # str
- :holder, :holder_id, :holder_type, # polymorphic cardholder association
- :inactive # a card is inactive. This is currently only meaningful for nonprofit cards
-
-
- attr_accessor :failure_message
-
-
- belongs_to :holder, polymorphic: true
- has_many :charges
- has_many :donations
- has_many :tickets
+ attr_accessor :failure_message
+ belongs_to :holder, polymorphic: true
+ has_many :charges
+ has_many :donations
+ has_many :tickets
end
diff --git a/app/models/charge.rb b/app/models/charge.rb
index d2ce3f47..371bbc94 100644
--- a/app/models/charge.rb
+++ b/app/models/charge.rb
@@ -1,36 +1,34 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
# A Charge represents a potential debit to a nonprofit's account on a credit card donation action.
-class Charge < ActiveRecord::Base
+class Charge < ApplicationRecord
+ # :amount,
+ # :fee,
+ # :stripe_charge_id,
+ # :status
- attr_accessible \
- :amount,
- :fee,
- :stripe_charge_id,
- :status
+ has_one :campaign, through: :donation
+ has_one :recurring_donation, through: :donation
+ has_many :tickets
+ has_many :events, through: :tickets
+ has_many :refunds
+ has_many :disputes
+ belongs_to :supporter
+ belongs_to :card
+ belongs_to :direct_debit_detail
+ belongs_to :nonprofit
+ belongs_to :donation
+ belongs_to :payment
+ scope :paid, -> { where(status: %w[available pending disbursed]) }
+ scope :not_paid, -> { where(status: [nil, 'failed']) }
+ scope :available, -> { where(status: 'available') }
+ scope :pending, -> { where(status: 'pending') }
+ scope :disbursed, -> { where(status: 'disbursed') }
- has_one :campaign, through: :donation
- has_one :recurring_donation, through: :donation
- has_many :tickets
- has_many :events, through: :tickets
- has_many :refunds
- has_many :disputes
- belongs_to :supporter
- belongs_to :card
- belongs_to :direct_debit_detail
- belongs_to :nonprofit
- belongs_to :donation
- belongs_to :payment
-
- scope :paid, ->{where(status: ["available", "pending", "disbursed"])}
- scope :not_paid, ->{where(status: [nil, "failed"])}
- scope :available, ->{where(status: "available")}
- scope :pending, ->{where(status: "pending")}
- scope :disbursed, ->{where(status: "disbursed")}
-
- def paid?
- self.status.in?(%w[available pending disbursed])
- end
-
+ def paid?
+ status.in?(%w[available pending disbursed])
+ end
end
diff --git a/app/models/comment.rb b/app/models/comment.rb
index e0491d49..b2510703 100644
--- a/app/models/comment.rb
+++ b/app/models/comment.rb
@@ -1,35 +1,35 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class Comment < ActiveRecord::Base
+class Comment < ApplicationRecord
+ # :host_id,
+ # :host_type, # parent: Event, Campaign, nil
+ # :profile_id,
+ # :body
- attr_accessible \
- :host_id, :host_type, #parent: Event, Campaign, nil
- :profile_id,
- :body
+ validates :profile, presence: true
+ validates :body, presence: true, length: { maximum: 200 }
- validates :profile, :presence => true
- validates :body, :presence => true, :length => {:maximum => 200}
+ has_one :activity, as: :attachment, dependent: :destroy
+ belongs_to :host, polymorphic: true
+ belongs_to :donation
+ belongs_to :profile
- has_one :activity, :as => :attachment, :dependent => :destroy
- belongs_to :host, :polymorphic => true
- belongs_to :donation
- belongs_to :profile
+ before_validation(on: :create) do
+ remove_newlines
+ end
- before_validation(:on => :create) do
- remove_newlines
- end
-
- after_create do
- self.create_activity({
- :desc => 'commented',
- :profile_id => self.profile_id,
- :host_id => self.host_id,
- :host_type => self.host_type,
- :body => self.body
- })
- end
-
- def remove_newlines
- self.body = self.body && self.body.gsub(/\n/,'')
- end
+ after_create do
+ create_activity(
+ desc: 'commented',
+ profile_id: profile_id,
+ host_id: host_id,
+ host_type: host_type,
+ body: body
+ )
+ end
+ def remove_newlines
+ self.body = body && body.delete("\n")
+ end
end
diff --git a/app/models/concerns/image/attachment_extensions.rb b/app/models/concerns/image/attachment_extensions.rb
new file mode 100644
index 00000000..296c29c0
--- /dev/null
+++ b/app/models/concerns/image/attachment_extensions.rb
@@ -0,0 +1,50 @@
+module Image::AttachmentExtensions
+ extend ActiveSupport::Concern
+ class_methods do
+ def has_one_attached_with_sizes(attribute_name, sizes)
+ if sizes.nil? || !sizes.is_a?(Hash) || !sizes.any?
+ raise ArgumentError, "You must pass a valid hash of sizes"
+ end
+ attribute = attribute_name.to_s
+
+ # clean up sizes
+ sizes.keys.each do |key|
+ value = sizes[key]
+ if value.is_a?(Numeric)
+ sizes[key] = [value, value]
+ elsif value.is_a?(Array) && value.count == 1 && value.all?{|i| i.is_a?(Numeric)}
+ sizes[key]= [value[0], value[0]]
+ elsif value.is_a?(Array) && value.count == 2 && value.all?{|i| i.is_a?(Numeric)}
+ sizes[key] = [value[0], value[1]]
+ else
+ raise ArgumentError, "#{value.to_s} was not a valid size."
+ end
+ end
+
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
+ def #{attribute}_by_size(size)
+ case (size)
+ #{sizes.map do |k,v|
+ <<-INNER
+ when :#{k.to_sym}
+ return #{attribute}.variant(resize_to_limit: [#{v[0]}, #{v[1]}])
+ INNER
+ end.join("\n")}
+ else
+ raise ArgumentError, ":" + size.to_s + " is not a valid size. Valid sizes are: #{sizes.keys.map{|i| ":" + i.to_s}.join(', ')}"
+ end
+ end
+ RUBY
+ end
+
+ def has_one_attached_with_default(attribute_name, default_path, **options)
+ after_save do
+ attribute = send(attribute_name)
+ unless attribute.attached?
+ attribute.attach(io: File.open(default_path), **options)
+ end
+ self
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/models/coupon.rb b/app/models/coupon.rb
index 1377d548..1318dd94 100644
--- a/app/models/coupon.rb
+++ b/app/models/coupon.rb
@@ -1,12 +1,14 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class Coupon < ActiveRecord::Base
- attr_accessible \
- :name,
- :victim_np_id,
- :paid, # boolean
- :nonprofit, :nonprofit_id
+class Coupon < ApplicationRecord
+ # :name,
+ # :victim_np_id,
+ # :paid, # boolean
+ # :nonprofit,
+ # :nonprofit_id
- scope :unpaid, -> {where(paid: [nil,false])}
+ scope :unpaid, -> { where(paid: [nil, false]) }
- validates_presence_of :name, :nonprofit_id, :victim_np_id
-end
\ No newline at end of file
+ validates_presence_of :name, :nonprofit_id, :victim_np_id
+end
diff --git a/app/models/create_model.rb b/app/models/create_model.rb
new file mode 100644
index 00000000..2c0fcc8c
--- /dev/null
+++ b/app/models/create_model.rb
@@ -0,0 +1,48 @@
+class CreateModel < Base
+ attr_accessor :nonprofit, :user
+ validates_presence_of :user
+ validates_presence_of :nonprofit
+ validate_nested_attribute :user, model_class: User
+ validate_nested_attribute :nonprofit, model_class: Nonprofit
+
+ before_validation do
+ nonprofit = Nonprofit.create(nonprofit) if !nonprofit.is_a? Nonprofit
+ user = User.create(user) if !nonprofit.is_a? Nonprofit
+ end
+
+ def save
+ if valid?
+ if nonprofit.save!
+ if user.save!
+ role = user.roles.build(host: nonprofit, name: 'nonprofit_admin')
+ role.save!
+
+ billing_plan = BillingPlan.find(Settings.default_bp.id)
+ b_sub = nonprofit.build_billing_subscription(billing_plan: billing_plan, status: 'active')
+ b_sub.save!
+ end
+ end
+ end
+ # rescue ActiveRecord::RecordInvalid => e
+ # class_to_name = { Nonprofit => 'nonprofit', User => 'user' }
+ # if class_to_name[e.record.class]
+ # errors = e.record.errors.keys.map do |k|
+ # errors = e.record.errors[k].uniq
+ # errors.map do |error|
+ # Grape::Exceptions::Validation.new(
+ # params: ["#{class_to_name[e.record.class]}[#{k}]"],
+ # value message: error
+ # )
+ # end
+ # end
+ # raise Grape::Exceptions::ValidationErrors.new(errors: errors.flatten)
+ # else
+ # raise e
+ # end
+ # end
+ end
+
+ def save!
+ raise 'runtime' unless save
+ end
+end
\ No newline at end of file
diff --git a/app/models/custom_field_join.rb b/app/models/custom_field_join.rb
index c38e9331..e304c262 100644
--- a/app/models/custom_field_join.rb
+++ b/app/models/custom_field_join.rb
@@ -1,25 +1,25 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class CustomFieldJoin < ActiveRecord::Base
+class CustomFieldJoin < ApplicationRecord
+ # :supporter,
+ # :supporter_id,
+ # :custom_field_master,
+ # :custom_field_master_id,
+ # :value
- attr_accessible \
- :supporter, :supporter_id,
- :custom_field_master, :custom_field_master_id,
- :value
+ validates :custom_field_master, presence: true
- validates :custom_field_master, presence: true
-
- belongs_to :custom_field_master
+ belongs_to :custom_field_master
belongs_to :supporter
- def self.create_with_name(nonprofit, h)
- cfm = nonprofit.custom_field_masters.find_by_name(h['name'])
- if cfm.nil?
- cfm = nonprofit.custom_field_masters.create(name: h['name'])
- end
- self.create({value: h['value'], custom_field_master_id: cfm.id, supporter_id: h['supporter_id']})
- end
-
- def name; custom_field_master.name; end
+ def self.create_with_name(nonprofit, h)
+ cfm = nonprofit.custom_field_masters.find_by_name(h['name'])
+ cfm = nonprofit.custom_field_masters.create(name: h['name']) if cfm.nil?
+ create(value: h['value'], custom_field_master_id: cfm.id, supporter_id: h['supporter_id'])
+ end
+ def name
+ custom_field_master.name
+end
end
-
diff --git a/app/models/custom_field_master.rb b/app/models/custom_field_master.rb
index ef6bb85c..15f5fe08 100644
--- a/app/models/custom_field_master.rb
+++ b/app/models/custom_field_master.rb
@@ -1,24 +1,24 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class CustomFieldMaster < ActiveRecord::Base
+class CustomFieldMaster < ApplicationRecord
+ # :nonprofit,
+ # :nonprofit_id,
+ # :name,
+ # :deleted,
+ # :created_at
- attr_accessible \
- :nonprofit, :nonprofit_id,
- :name,
- :deleted,
- :created_at
+ validates :name, presence: true
+ validate :no_dupes, on: :create
- validates :name, presence: true
- validate :no_dupes, on: :create
+ belongs_to :nonprofit
+ has_many :custom_field_joins, dependent: :destroy
- belongs_to :nonprofit
- has_many :custom_field_joins, dependent: :destroy
+ scope :not_deleted, -> { where(deleted: [nil, false]) }
- scope :not_deleted, ->{where(deleted: [nil,false])}
-
- def no_dupes
- return self if nonprofit.nil?
- errors.add(:base, "Duplicate custom field") if nonprofit.custom_field_masters.not_deleted.where(name: name).any?
- end
+ def no_dupes
+ return self if nonprofit.nil?
+ errors.add(:base, 'Duplicate custom field') if nonprofit.custom_field_masters.not_deleted.where(name: name).any?
+ end
end
-
diff --git a/app/models/direct_debit_detail.rb b/app/models/direct_debit_detail.rb
index ba8fbe67..f3a7755d 100644
--- a/app/models/direct_debit_detail.rb
+++ b/app/models/direct_debit_detail.rb
@@ -1,8 +1,14 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class DirectDebitDetail < ActiveRecord::Base
- attr_accessible :iban, :account_holder_name, :bic, :supporter_id, :holder
+class DirectDebitDetail < ApplicationRecord
+ # :iban,
+ # :account_holder_name,
+ # :bic,
+ # :supporter_id,
+ # :holder
has_many :donations
has_many :charges
- belongs_to :holder, class_name: Supporter
+ belongs_to :holder, class_name: 'Supporter'
end
diff --git a/app/models/dispute.rb b/app/models/dispute.rb
index 722768b3..fb919039 100644
--- a/app/models/dispute.rb
+++ b/app/models/dispute.rb
@@ -1,19 +1,18 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class Dispute < ActiveRecord::Base
+class Dispute < ApplicationRecord
+ Reasons = %i[unrecognized duplicate fraudulent subscription_canceled product_unacceptable product_not_received unrecognized credit_not_processed goods_services_returned_or_refused goods_services_cancelled incorrect_account_details insufficient_funds bank_cannot_process debit_not_authorized general].freeze
- Reasons = [:unrecognized, :duplicate, :fraudulent, :subscription_canceled, :product_unacceptable, :product_not_received, :unrecognized, :credit_not_processed, :goods_services_returned_or_refused, :goods_services_cancelled, :incorrect_account_details, :insufficient_funds, :bank_cannot_process, :debit_not_authorized, :general]
-
- Statuses = [:needs_response, :under_review, :won, :lost, :lost_and_paid]
-
- attr_accessible \
- :gross_amount, # int
- :charge_id, :charge,
- :payment_id, :payment,
- :status,
- :reason
+ Statuses = %i[needs_response under_review won lost lost_and_paid].freeze
+ # :gross_amount, # int
+ # :charge_id,
+ # :charge,
+ # :payment_id,
+ # :payment,
+ # :status,
+ # :reason
belongs_to :charge
belongs_to :payment
-
end
-
diff --git a/app/models/donation.rb b/app/models/donation.rb
index d014f737..501e2d86 100644
--- a/app/models/donation.rb
+++ b/app/models/donation.rb
@@ -1,48 +1,48 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class Donation < ActiveRecord::Base
+class Donation < ApplicationRecord
+ # :date, # datetime (when this donation was made)
+ # :amount, # int (in cents)
+ # :recurring, # bool
+ # :anonymous, # bool
+ # :email, # str (cached email of the donor)
+ # :designation, # text
+ # :dedication, # text
+ # :comment, # text
+ # :origin_url, # text
+ # :nonprofit_id, :nonprofit,
+ # :card_id, :card, # Card with which any charges were made
+ # :supporter_id, :supporter,
+ # :profile_id, :profile,
+ # :campaign_id, :campaign,
+ # :payment_id, :payment,
+ # :event_id, :event,
+ # :direct_debit_detail_id, :direct_debit_detail,
+ # :payment_provider
- attr_accessible \
- :date, # datetime (when this donation was made)
- :amount, # int (in cents)
- :recurring, # bool
- :anonymous, # bool
- :email, # str (cached email of the donor)
- :designation, # text
- :dedication, # text
- :comment, # text
- :origin_url, # text
- :nonprofit_id, :nonprofit,
- :card_id, :card, # Card with which any charges were made
- :supporter_id, :supporter,
- :profile_id, :profile,
- :campaign_id, :campaign,
- :payment_id, :payment,
- :event_id, :event,
- :direct_debit_detail_id, :direct_debit_detail,
- :payment_provider
+ validates :amount, presence: true, numericality: { only_integer: true }
+ validates :supporter, presence: true
+ validates :nonprofit, presence: true
+ validates_associated :charges
+ validates :payment_provider, inclusion: { in: %w[credit_card sepa] }, allow_blank: true
- validates :amount, presence: true, numericality: { only_integer: true }
- validates :supporter, presence: true
- validates :nonprofit, presence: true
- validates_associated :charges
- validates :payment_provider, inclusion: { in: %(credit_card sepa) }, allow_blank: true
+ has_many :charges
+ has_many :campaign_gifts, dependent: :destroy
+ has_many :campaign_gift_options, through: :campaign_gifts
+ has_many :activities, as: :attachment, dependent: :destroy
+ has_many :payments
+ has_one :recurring_donation
+ has_one :payment
+ has_one :offsite_payment
+ has_one :tracking
+ belongs_to :supporter
+ belongs_to :card
+ belongs_to :direct_debit_detail
+ belongs_to :profile
+ belongs_to :nonprofit
+ belongs_to :campaign
+ belongs_to :event
- has_many :charges
- has_many :campaign_gifts, dependent: :destroy
- has_many :campaign_gift_options, through: :campaign_gifts
- has_many :activities, as: :attachment, dependent: :destroy
- has_many :payments
- has_one :recurring_donation
- has_one :payment
- has_one :offsite_payment
- has_one :tracking
- belongs_to :supporter
- belongs_to :card
- belongs_to :direct_debit_detail
- belongs_to :profile
- belongs_to :nonprofit
- belongs_to :campaign
- belongs_to :event
-
- scope :anonymous, -> {where(anonymous: true)}
+ scope :anonymous, -> { where(anonymous: true) }
end
diff --git a/app/models/email_draft.rb b/app/models/email_draft.rb
index 9614c13c..bc4296f3 100644
--- a/app/models/email_draft.rb
+++ b/app/models/email_draft.rb
@@ -1,16 +1,14 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class EmailDraft < ActiveRecord::Base
+class EmailDraft < ApplicationRecord
+ # :nonprofit, :nonprofit_id,
+ # :name,
+ # :deleted,
+ # :value,
+ # :created_at
- attr_accessible \
- :nonprofit, :nonprofit_id,
- :name,
- :deleted,
- :value,
- :created_at
-
- belongs_to :nonprofit
-
- scope :not_deleted, ->{where(deleted: [nil,false])}
+ belongs_to :nonprofit
+ scope :not_deleted, -> { where(deleted: [nil, false]) }
end
-
diff --git a/app/models/email_list.rb b/app/models/email_list.rb
index ea64e773..30ded59d 100644
--- a/app/models/email_list.rb
+++ b/app/models/email_list.rb
@@ -1,6 +1,11 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class EmailList < ActiveRecord::Base
- attr_accessible :list_name, :mailchimp_list_id, :nonprofit, :tag_master
+class EmailList < ApplicationRecord
+ # :list_name,
+ # :mailchimp_list_id,
+ # :nonprofit,
+ # :tag_master
belongs_to :nonprofit
belongs_to :tag_master
end
diff --git a/app/models/email_setting.rb b/app/models/email_setting.rb
index c4f8bf2e..8624def0 100644
--- a/app/models/email_setting.rb
+++ b/app/models/email_setting.rb
@@ -1,16 +1,15 @@
-# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class EmailSetting < ActiveRecord::Base
+# frozen_string_literal: true
- attr_accessible \
- :user_id, :user,
- :nonprofit_id, :nonprofit,
- :notify_payments,
- :notify_campaigns,
- :notify_events,
- :notify_payouts,
- :notify_recurring_donations
+# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
+class EmailSetting < ApplicationRecord
+ # :user_id, :user,
+ # :nonprofit_id, :nonprofit,
+ # :notify_payments,
+ # :notify_campaigns,
+ # :notify_events,
+ # :notify_payouts,
+ # :notify_recurring_donations
belongs_to :nonprofit
belongs_to :user
-
end
diff --git a/app/models/errors/active_model_error.rb b/app/models/errors/active_model_error.rb
new file mode 100644
index 00000000..5963e621
--- /dev/null
+++ b/app/models/errors/active_model_error.rb
@@ -0,0 +1,5 @@
+
+
+class Errors::ActiveModelError < StandardError
+
+end
\ No newline at end of file
diff --git a/app/models/errors/message_invalid.rb b/app/models/errors/message_invalid.rb
new file mode 100644
index 00000000..b4fed5a1
--- /dev/null
+++ b/app/models/errors/message_invalid.rb
@@ -0,0 +1,17 @@
+
+class Errors::MessageInvalid < Errors::ActiveModelError
+
+ attr_reader :record
+ def initialize(record=nil)
+ if record
+ @record = record
+ errors = @record.errors.full_messages.join(", ")
+ message = I18n.t(:"#{@record.class.i18n_scope}.errors.messages.record_invalid", errors: errors, default: :"errors.messages.record_invalid")
+ else
+ message = "Record invalid"
+ end
+
+ super(message)
+
+ end
+end
\ No newline at end of file
diff --git a/app/models/event.rb b/app/models/event.rb
index 4face493..1e53eca2 100644
--- a/app/models/event.rb
+++ b/app/models/event.rb
@@ -1,104 +1,110 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class Event < ActiveRecord::Base
+class Event < ApplicationRecord
+ include Image::AttachmentExtensions
+ # :deleted, #bool for soft-delete
+ # :name, # str
+ # :tagline, # str
+ # :summary, # text
+ # :body, # text (html)
+ # :end_datetime,
+ # :start_datetime,
+ # :latitude, # float
+ # :longitude, # float
+ # :location, # str
+ # :city, # str
+ # :state_code, # str
+ # :address, # str
+ # :zip_code, # str
+ # :main_image, # str
+ # :remove_main_image, # for carrierwave
+ # :background_image, # str
+ # :remove_background_image, # bool carrierwave
+ # :published, # bool
+ # :slug, # str
+ # :directions, # text
+ # :venue_name, # str
+ # :profile_id, # creator
+ # :ticket_levels_attributes,
+ # :show_total_raised, # bool
+ # :show_total_count, # bool
+ # :hide_activity_feed, # bool
+ # :nonprofit_id, # host
+ # :hide_title, # bool
+ # :organizer_email, # string
+ # :receipt_message # text
- attr_accessible \
- :deleted, #bool for soft-delete
- :name, # str
- :tagline, # str
- :summary, # text
- :body, # text (html)
- :end_datetime,
- :start_datetime,
- :latitude, # float
- :longitude, # float
- :location, # str
- :city, # str
- :state_code, # str
- :address, # str
- :zip_code, # str
- :main_image, # str
- :remove_main_image, # for carrierwave
- :background_image, # str
- :remove_background_image, # bool carrierwave
- :published, # bool
- :slug, # str
- :directions, # text
- :venue_name, # str
- :profile_id, # creator
- :ticket_levels_attributes,
- :show_total_raised, # bool
- :show_total_count, # bool
- :hide_activity_feed, # bool
- :nonprofit_id, # host
- :hide_title, # bool
- :organizer_email, # string
- :receipt_message # text
+ validates :name, presence: true
+ validates :end_datetime, presence: true
+ validates :start_datetime, presence: true
+ validates :address, presence: true
+ validates :city, presence: true
+ validates :state_code, presence: true
+ validates :slug, presence: true, uniqueness: { scope: :nonprofit_id, message: 'You already have an event with that URL' }
+ validates :nonprofit_id, presence: true
+ validates :profile_id, presence: true
- validates :name, :presence => true
- validates :end_datetime, :presence => true
- validates :start_datetime, :presence => true
- validates :address, :presence => true
- validates :city, :presence => true
- validates :state_code, :presence => true
- validates :slug, :presence => true, uniqueness: {scope: :nonprofit_id, message: 'You already have an event with that URL'}
- validates :nonprofit_id, :presence => true
- validates :profile_id, :presence => true
-
- belongs_to :nonprofit
- belongs_to :profile
- has_many :donations
- has_many :charges, through: :tickets
- has_many :supporters, through: :donations
- has_many :recurring_donations
- has_many :ticket_levels, :dependent => :destroy
+ belongs_to :nonprofit
+ belongs_to :profile
+ has_many :donations
+ has_many :charges, through: :tickets
+ has_many :supporters, through: :donations
+ has_many :recurring_donations
+ has_many :ticket_levels, dependent: :destroy
has_many :event_discounts, dependent: :destroy
- has_many :tickets
- has_many :payments, through: :tickets
- has_many :roles, as: :host, dependent: :destroy
- has_many :comments, as: :host, dependent: :destroy
- has_many :activities, as: :host, dependent: :destroy
+ has_many :tickets
+ has_many :payments, through: :tickets
+ has_many :roles, as: :host, dependent: :destroy
+ has_many :comments, as: :host, dependent: :destroy
+ has_many :activities, as: :host, dependent: :destroy
+ geocoded_by :full_address
- geocoded_by :full_address
+ accepts_nested_attributes_for :ticket_levels, allow_destroy: true
+ has_one_attached :main_image
+ has_one_attached :background_image
- accepts_nested_attributes_for :ticket_levels, :allow_destroy => true
+ has_one_attached_with_sizes :main_image, {normal: 400, thumb: 100}
+ has_one_attached_with_sizes :background_image, {normal: [1000, 600]}
- mount_uploader :main_image, EventMainImageUploader
- mount_uploader :background_image, EventBackgroundImageUploader
+ has_one_attached_with_default(:main_image, Image::DefaultProfileUrl,
+ filename: "main_image_#{SecureRandom.uuid}#{Pathname.new(Image::DefaultProfileUrl).extname}")
- scope :not_deleted, -> {where(deleted: [nil,false])}
- scope :deleted, -> {where(deleted: true)}
- scope :published, -> {where(:published => true)}
- scope :upcoming, -> {where("start_datetime >= ?", Date.today).published}
- scope :past, -> {where("end_datetime < ?", Date.today).published}
- scope :unpublished, -> {where("published != ?", true)}
+ has_one_attached_with_default(:background_image, Image::DefaultCampaignUrl,
+ filename: "background_image_#{SecureRandom.uuid}#{Pathname.new(Image::DefaultCampaignUrl).extname}")
+
- validates :slug, uniqueness: {scope: :nonprofit_id, message: 'You already have a campaign with that name.'}
+ scope :not_deleted, -> { where(deleted: [nil, false]) }
+ scope :deleted, -> { where(deleted: true) }
+ scope :published, -> { where(published: true) }
+ scope :upcoming, -> { where('start_datetime >= ?', Date.today).published }
+ scope :past, -> { where('end_datetime < ?', Date.today).published }
+ scope :unpublished, -> { where('published != ?', true) }
- before_validation(on: :create) do
- unless self.slug
- self.slug = Format::Url.convert_to_slug(name)
- end
- self.published = false if self.published.nil?
- self.total_raised ||= 0
+ validates :slug, uniqueness: { scope: :nonprofit_id, message: 'You already have a campaign with that name.' }
+
+ before_validation(on: :create) do
+ self.slug = Format::Url.convert_to_slug(name) unless slug
+ self.published = false if published.nil?
+ self.total_raised ||= 0
self
- end
-
- after_validation :geocode
-
- after_create do
- user = self.profile.user
- Role.create(name: :event_editor, user_id: user.id, host: self)
- EventMailer.delay.creation_followup(self)
- self
- end
-
- def url
- "#{self.nonprofit.url}/events/#{self.slug}"
- end
-
- def full_address
- Format::Address.full_address(self.address, self.city, self.state_code, self.zip_code)
end
+ after_validation :geocode
+
+ after_create do
+ user = profile.user
+ Role.create(name: :event_editor, user_id: user.id, host: self)
+ EventCreateJob.perform_later self
+ self
+ end
+
+ def url
+ "#{nonprofit.url}/events/#{slug}"
+ end
+
+ def full_address
+ Format::Address.full_address(address, city, state_code, zip_code)
+ end
end
diff --git a/app/models/event_discount.rb b/app/models/event_discount.rb
index 7e6a69a0..cf6d7a1e 100644
--- a/app/models/event_discount.rb
+++ b/app/models/event_discount.rb
@@ -1,12 +1,12 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class EventDiscount < ActiveRecord::Base
- attr_accessible \
- :code,
- :event_id,
- :name,
- :percent
+class EventDiscount < ApplicationRecord
+ # :code,
+ # :event_id,
+ # :name,
+ # :percent
belongs_to :event
has_many :tickets
-
end
diff --git a/app/models/export.rb b/app/models/export.rb
index e49d5609..a48e92b9 100644
--- a/app/models/export.rb
+++ b/app/models/export.rb
@@ -1,8 +1,19 @@
-# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class Export < ActiveRecord::Base
+# frozen_string_literal: true
+# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
+class Export < ApplicationRecord
+ # :exception,
+ # :nonprofit,
+ # :status,
+ # :user,
+ # :export_type,
+ # :parameters,
+ # :ended,
+ # :url,
+ # :user_id,
+ # :nonprofit_id
+
STATUS = %w[queued started completed failed].freeze
- attr_accessible :exception, :nonprofit, :status, :user, :export_type, :parameters, :ended, :url, :user_id, :nonprofit_id
belongs_to :nonprofit
belongs_to :user
diff --git a/app/models/full_contact_info.rb b/app/models/full_contact_info.rb
index 712579fa..ee910cb1 100644
--- a/app/models/full_contact_info.rb
+++ b/app/models/full_contact_info.rb
@@ -1,23 +1,24 @@
-# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class FullContactInfo < ActiveRecord::Base
- attr_accessible \
- :email,
- :full_name,
- :gender,
- :city,
- :county,
- :state_code,
- :country,
- :continent,
- :age,
- :age_range,
- :location_general,
- :supporter_id, :supporter,
- :websites
+# frozen_string_literal: true
- has_many :full_contact_photos
- has_many :full_contact_social_profiles
- has_many :full_contact_orgs
- has_many :full_contact_topics
+# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
+class FullContactInfo < ApplicationRecord
+ # :email,
+ # :full_name,
+ # :gender,
+ # :city,
+ # :county,
+ # :state_code,
+ # :country,
+ # :continent,
+ # :age,
+ # :age_range,
+ # :location_general,
+ # :supporter_id, :supporter,
+ # :websites
+
+ has_many :full_contact_photos
+ has_many :full_contact_social_profiles
+ has_many :full_contact_orgs
+ has_many :full_contact_topics
belongs_to :supporter
end
diff --git a/app/models/full_contact_org.rb b/app/models/full_contact_org.rb
index a8b4ce1b..a73a708a 100644
--- a/app/models/full_contact_org.rb
+++ b/app/models/full_contact_org.rb
@@ -1,16 +1,15 @@
-# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class FullContactOrg < ActiveRecord::Base
+# frozen_string_literal: true
- attr_accessible \
- :name,
- :is_primary,
- :name,
- :start_date,
- :end_date,
- :title,
- :current,
- :full_contact_info_id, :full_contact_info
+# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
+class FullContactOrg < ApplicationRecord
+ # :name,
+ # :is_primary,
+ # :name,
+ # :start_date,
+ # :end_date,
+ # :title,
+ # :current,
+ # :full_contact_info_id, :full_contact_info
belongs_to :full_contact_info
-
end
diff --git a/app/models/full_contact_photo.rb b/app/models/full_contact_photo.rb
index 258a764f..647d542a 100644
--- a/app/models/full_contact_photo.rb
+++ b/app/models/full_contact_photo.rb
@@ -1,13 +1,14 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class FullContactPhoto < ActiveRecord::Base
- attr_accessible \
- :full_contact_info,
- :full_contact_info_id,
- :type_id, # i.e. twitter, linkedin, facebook
- :is_primary, #bool
- :url #string
+class FullContactPhoto < ApplicationRecord
+ # :full_contact_info,
+ # :full_contact_info_id,
+ # :type_id, # i.e. twitter, linkedin, facebook
+ # :is_primary, #bool
+ # :url #string
- belongs_to :full_contact_info
+ belongs_to :full_contact_info
- validates_presence_of :full_contact_info
-end
\ No newline at end of file
+ validates_presence_of :full_contact_info
+end
diff --git a/app/models/full_contact_social_profile.rb b/app/models/full_contact_social_profile.rb
index 047160ea..717829fe 100644
--- a/app/models/full_contact_social_profile.rb
+++ b/app/models/full_contact_social_profile.rb
@@ -1,15 +1,16 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class FullContactSocialProfile < ActiveRecord::Base
- attr_accessible \
- :full_contact_info,
- :full_contact_info_id,
- :type_id, # i.e. twitter, linkedin, facebook
- :username, #string
- :uid, # string
- :bio, #string
- :url #string
+class FullContactSocialProfile < ApplicationRecord
+ # :full_contact_info,
+ # :full_contact_info_id,
+ # :type_id, # i.e. twitter, linkedin, facebook
+ # :username, #string
+ # :uid, # string
+ # :bio, #string
+ # :url #string
- belongs_to :full_contact_info
+ belongs_to :full_contact_info
- validates_presence_of :full_contact_info
-end
\ No newline at end of file
+ validates_presence_of :full_contact_info
+end
diff --git a/app/models/full_contact_topic.rb b/app/models/full_contact_topic.rb
index 475f9c27..952195a3 100644
--- a/app/models/full_contact_topic.rb
+++ b/app/models/full_contact_topic.rb
@@ -1,11 +1,10 @@
-# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class FullContactTopic < ActiveRecord::Base
+# frozen_string_literal: true
- attr_accessible \
- :provider,
- :value,
- :full_contact_info_id, :full_contact_info
+# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
+class FullContactTopic < ApplicationRecord
+ # :provider,
+ # :value,
+ # :full_contact_info_id, :full_contact_info
belongs_to :full_contact_info
-
end
diff --git a/app/models/image_attachment.rb b/app/models/image_attachment.rb
index d6afb9a4..23e89904 100644
--- a/app/models/image_attachment.rb
+++ b/app/models/image_attachment.rb
@@ -1,10 +1,14 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class ImageAttachment < ActiveRecord::Base
+class ImageAttachment < ApplicationRecord
+ include Image::AttachmentExtensions
+ # :parent_id,
+ # :file
+ has_one_attached :file
- attr_accessible :parent_id, :file
- mount_uploader :file, ImageAttachmentUploader
-
- # not sure if poly parent is used on this model, as all values are nil in db
- belongs_to :parent, :polymorphic => true
+ has_one_attached_with_sizes :file, {large: [600, 400], medium: [400, 266], small: [400,266], thumb_explore: [200,133]}
+ # not sure if poly parent is used on this model, as all values are nil in db
+ belongs_to :parent, polymorphic: true
end
diff --git a/app/models/import.rb b/app/models/import.rb
index b4e3f681..4c6453a4 100644
--- a/app/models/import.rb
+++ b/app/models/import.rb
@@ -1,19 +1,17 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class Import < ActiveRecord::Base
+class Import < ApplicationRecord
+ # :user_id, :user,
+ # :email, # email of the user who ma
+ # :nonprofit_id, :nonprofit,
+ # :row_count,
+ # :imported_count,
+ # :date
- attr_accessible \
- :user_id, :user,
- :email, # email of the user who ma
- :nonprofit_id, :nonprofit,
- :row_count,
- :imported_count,
- :date
-
- has_many :supporters
- belongs_to :nonprofit
- belongs_to :user
-
- validates :user, presence: true
+ has_many :supporters
+ belongs_to :nonprofit
+ belongs_to :user
+ validates :user, presence: true
end
-
diff --git a/app/models/miscellaneous_np_info.rb b/app/models/miscellaneous_np_info.rb
index 2b15029a..3bd32dbb 100644
--- a/app/models/miscellaneous_np_info.rb
+++ b/app/models/miscellaneous_np_info.rb
@@ -1,9 +1,9 @@
-# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class MiscellaneousNpInfo < ActiveRecord::Base
+# frozen_string_literal: true
- attr_accessible \
- :donate_again_url,
- :change_amount_message
+# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
+class MiscellaneousNpInfo < ApplicationRecord
+ # :donate_again_url,
+ # :change_amount_message
belongs_to :nonprofit
end
diff --git a/app/models/nonprofit.rb b/app/models/nonprofit.rb
index 421b59b1..c1029141 100755
--- a/app/models/nonprofit.rb
+++ b/app/models/nonprofit.rb
@@ -1,56 +1,58 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class Nonprofit < ActiveRecord::Base
+class Nonprofit < ApplicationRecord
+ attr_accessor :register_np_only, :user_id, :user
+ Categories = ['Public Benefit', 'Human Services', 'Education', 'Civic Duty', 'Human Rights', 'Animals', 'Environment', 'Health', 'Arts, Culture, Humanities', 'International', 'Children', 'Religion', 'LGBTQ', "Women's Rights", 'Disaster Relief', 'Veterans'].freeze
- Categories = ["Public Benefit", "Human Services", "Education", "Civic Duty", "Human Rights", "Animals", "Environment", "Health", "Arts, Culture, Humanities", "International", "Children", "Religion", "LGBTQ", "Women's Rights", "Disaster Relief", "Veterans"]
-
- attr_accessible \
- :name, # str
- :stripe_account_id, # str
- :summary, # text: paragraph-sized organization summary
- :tagline, # str
- :email, # str: public organization contact email
- :phone, # str: public org contact phone
- :main_image, # str: url of featured image - first image in profile carousel
- :second_image, # str: url of 2nd image in carousel
- :third_image, # str: url of 3rd image in carousel
- :background_image, # str: url of large profile background
- :remove_background_image, #bool carrierwave
- :logo, # str: small logo image url for searching
- :zip_code, # int
- :website, # str: their own website url
- :categories, # text [str]: see the constant Categories
- :achievements, # text [str]: highlights about this org
- :full_description, # text
- :state_code, # str: two-letter state code (eg. CA)
- :statement, # str: bank statement for donations towards the nonprofit
- :city, # str
- :slug, # str
- :city_slug, #str
- :state_code_slug, #str
- :ein, # str: employee identification number
- :published, # boolean; whether to display this profile
- :vetted, # bool: Whether a super admin (one of CommitChange's employees) have approved this org
- :verification_status, # str (either 'pending', 'unverified', 'escalated', 'verified' -- whether the org has submitted the identity verification form and it has been approved)
- :latitude, # float: geocoder gem
- :longitude, # float: geocoder gem
- :timezone, # str
- :address, # text
- :thank_you_note, # text
- :referrer, # str
- :no_anon, # bool: whether to allow anonymous donations
- :roles_attributes,
- :brand_font, #string (lowercase key eg. 'helvetica')
- :brand_color, #string (hex color value)
- :hide_activity_feed, # bool
- :tracking_script,
- :facebook, #string (url)
- :twitter, #string (url)
- :youtube, #string (url)
- :instagram, #string (url)
- :blog, #string (url)
- :card_failure_message_top, # text
- :card_failure_message_bottom, # text
- :autocomplete_supporter_address # boolean
+ include Image::AttachmentExtensions
+ # :name, # str
+ # :stripe_account_id, # str
+ # :summary, # text: paragraph-sized organization summary
+ # :tagline, # str
+ # :email, # str: public organization contact email
+ # :phone, # str: public org contact phone
+ # :main_image, # str: url of featured image - first image in profile carousel
+ # :second_image, # str: url of 2nd image in carousel
+ # :third_image, # str: url of 3rd image in carousel
+ # :background_image, # str: url of large profile background
+ # :remove_background_image, #bool carrierwave
+ # :logo, # str: small logo image url for searching
+ # :zip_code, # int
+ # :website, # str: their own website url
+ # :categories, # text [str]: see the constant Categories
+ # :achievements, # text [str]: highlights about this org
+ # :full_description, # text
+ # :state_code, # str: two-letter state code (eg. CA)
+ # :statement, # str: bank statement for donations towards the nonprofit
+ # :city, # str
+ # :slug, # str
+ # :city_slug, #str
+ # :state_code_slug, #str
+ # :ein, # str: employee identification number
+ # :published, # boolean; whether to display this profile
+ # :vetted, # bool: Whether a super admin (one of CommitChange's employees) have approved this org
+ # :verification_status, # str (either 'pending', 'unverified', 'escalated', 'verified' -- whether the org has submitted the identity verification form and it has been approved)
+ # :latitude, # float: geocoder gem
+ # :longitude, # float: geocoder gem
+ # :timezone, # str
+ # :address, # text
+ # :thank_you_note, # text
+ # :referrer, # str
+ # :no_anon, # bool: whether to allow anonymous donations
+ # :roles_attributes,
+ # :brand_font, #string (lowercase key eg. 'helvetica')
+ # :brand_color, #string (hex color value)
+ # :hide_activity_feed, # bool
+ # :tracking_script,
+ # :facebook, #string (url)
+ # :twitter, #string (url)
+ # :youtube, #string (url)
+ # :instagram, #string (url)
+ # :blog, #string (url)
+ # :card_failure_message_top, # text
+ # :card_failure_message_bottom, # text
+ # :autocomplete_supporter_address # boolean
has_many :payouts
has_many :charges
@@ -64,16 +66,18 @@ class Nonprofit < ActiveRecord::Base
has_many :campaigns, dependent: :destroy
has_many :events, dependent: :destroy
has_many :tickets, through: :events
+ has_many :roles, as: :host, dependent: :destroy
has_many :users, through: :roles
has_many :tag_masters, dependent: :destroy
has_many :custom_field_masters, dependent: :destroy
- has_many :roles, as: :host, dependent: :destroy
+
has_many :activities, as: :host, dependent: :destroy
has_many :imports
has_many :email_settings
has_many :cards, as: :holder
- has_one :bank_account, dependent: :destroy, conditions: "COALESCE(deleted, false) = false"
+ has_one :bank_account, -> { where('COALESCE(deleted, false) = false') },
+ dependent: :destroy
has_one :billing_subscription, dependent: :destroy
has_one :billing_plan, through: :billing_subscription
has_one :miscellaneous_np_info
@@ -81,19 +85,42 @@ class Nonprofit < ActiveRecord::Base
validates :name, presence: true
validates :city, presence: true
validates :state_code, presence: true
- validates :email, format: { with: Email::Regex }, allow_blank: true
- validates_uniqueness_of :slug, scope: [:city_slug, :state_code_slug]
+ validates_format_of :email, with: Email::Regex, allow_nil: true
+ validates_format_of :website, with: URI.regexp(['https', 'http']), allow_nil: true
validates_presence_of :slug
+ validates_uniqueness_of :slug, scope: %i[city_slug state_code_slug]
- scope :vetted, -> {where(vetted: true)}
- scope :identity_verified, -> {where(verification_status: 'verified')}
- scope :published, -> {where(published: true)}
+ validates_presence_of :user_id, on: :create, unless: -> {register_np_only}
+ validate :user_is_valid, on: :create, unless: -> {register_np_only}
+ validate :user_registerable_as_admin, on: :create, unless: -> {register_np_only}
- mount_uploader :main_image, NonprofitUploader
- mount_uploader :second_image, NonprofitUploader
- mount_uploader :third_image, NonprofitUploader
- mount_uploader :background_image, NonprofitBackgroundUploader
- mount_uploader :logo, NonprofitLogoUploader
+ scope :vetted, -> { where(vetted: true) }
+ scope :identity_verified, -> { where(verification_status: 'verified') }
+ scope :published, -> { where(published: true) }
+
+ has_one_attached :main_image
+ has_one_attached :second_image
+ has_one_attached :third_image
+ has_one_attached :background_image
+ has_one_attached :logo
+
+ # way too wordy
+ has_one_attached_with_sizes(:logo, {small: 30, normal: 100, large: 180})
+ has_one_attached_with_sizes(:background_image, {normal: [1000,600]})
+ has_one_attached_with_sizes(:main_image, {nonprofit_carousel: [590, 338], thumb: [188, 120], thumb_explore: [100, 100]})
+ has_one_attached_with_sizes(:second_image, {nonprofit_carousel: [590, 338], thumb: [188, 120], thumb_explore: [100, 100]})
+ has_one_attached_with_sizes(:third_image, {nonprofit_carousel: [590, 338], thumb: [188, 120], thumb_explore: [100, 100]})
+
+ has_one_attached_with_default(:logo, Image::DefaultProfileUrl,
+ filename: "logo_#{SecureRandom.uuid}#{Pathname.new(Image::DefaultProfileUrl).extname}")
+ has_one_attached_with_default(:background_image, Image::DefaultNonprofitUrl,
+ filename: "background_image_#{SecureRandom.uuid}#{Pathname.new(Image::DefaultNonprofitUrl).extname}")
+ has_one_attached_with_default(:main_image, Image::DefaultProfileUrl,
+ filename: "main_image_#{SecureRandom.uuid}#{Pathname.new(Image::DefaultProfileUrl).extname}")
+ has_one_attached_with_default(:second_image, Image::DefaultProfileUrl,
+ filename: "second_image_#{SecureRandom.uuid}#{Pathname.new(Image::DefaultProfileUrl).extname}")
+ has_one_attached_with_default(:third_image, Image::DefaultProfileUrl,
+ filename: "third_image_#{SecureRandom.uuid}#{Pathname.new(Image::DefaultProfileUrl).extname}")
serialize :achievements, Array
serialize :categories, Array
@@ -101,20 +128,22 @@ class Nonprofit < ActiveRecord::Base
geocoded_by :full_address
before_validation(on: :create) do
- self.set_slugs
+ set_slugs
+ set_user
self
end
+ after_create :build_admin_role, unless: -> {register_np_only}
+
# Register (create) a nonprofit with an initial admin
def self.register(user, params)
- np = self.create ConstructNonprofit.construct(user, params)
+ np = create ConstructNonprofit.construct(user, params)
role = Role.create(user: user, name: 'nonprofit_admin', host: np) if np.valid?
- return np
+ np
end
-
def nonprofit_personnel_emails
- self.roles.nonprofit_personnel.joins(:user).pluck('users.email')
+ roles.nonprofit_personnel.joins(:user).pluck('users.email')
end
def total_recurring
@@ -123,62 +152,78 @@ class Nonprofit < ActiveRecord::Base
def donation_history_monthly
donation_history_monthly = []
- donations.order("created_at")
- .group_by{|d| d.created_at.beginning_of_month}
- .each{|_, ds| donation_history_monthly.push(ds.map(&:amount).sum)}
+ donations.order('created_at')
+ .group_by { |d| d.created_at.beginning_of_month }
+ .each { |_, ds| donation_history_monthly.push(ds.map(&:amount).sum) }
donation_history_monthly
end
def as_json(options = {})
h = super(options)
- h[:url] = self.url
+ h[:url] = url
h
end
def url
- "/#{self.state_code_slug}/#{self.city_slug}/#{self.slug}"
+ "/#{state_code_slug}/#{city_slug}/#{slug}"
end
def set_slugs
- unless (self.slug)
- self.slug = Format::Url.convert_to_slug self.name
- end
- unless (self.city_slug)
- self.city_slug = Format::Url.convert_to_slug self.city
- end
+ self.slug = Format::Url.convert_to_slug name unless slug
+ self.city_slug = Format::Url.convert_to_slug city unless city_slug
- unless (self.state_code_slug)
- self.state_code_slug = Format::Url.convert_to_slug self.state_code
+ unless state_code_slug
+ self.state_code_slug = Format::Url.convert_to_slug state_code
+ end
+ if Nonprofit.where(slug: slug, city_slug: city_slug, state_code_slug: state_code_slug).any?
+ correct_nonunique_slug
+ end
+ self
+ end
+
+ def correct_nonunique_slug
+ begin
+ slug = SlugNonprofitNamingAlgorithm.new(self.state_code_slug, self.city_slug).create_copy_name(self.slug)
+ self.slug = slug
+ rescue UnableToCreateNameCopyError
+ errors.add(:slug, "could not be created.")
+ end
+ end
+
+ def set_user
+ if (user_id && User.where(id: user_id).any?)
+ @user = User.find(user_id)
end
self
end
def full_address
- Format::Address.full_address(self.address, self.city, self.state_code)
+ Format::Address.full_address(address, city, state_code)
end
def total_raised
- QueryPayments.get_payout_totals( QueryPayments.ids_for_payout(self.id))['net_amount']
+ QueryPayments.get_payout_totals(QueryPayments.ids_for_payout(id))['net_amount']
end
def can_make_payouts
- self.vetted &&
- self.verification_status == 'verified' &&
- self.bank_account &&
- !self.bank_account.pending_verification
+ vetted &&
+ verification_status == 'verified' &&
+ bank_account &&
+ !bank_account.pending_verification
end
def active_cards
- cards.where("COALESCE(cards.inactive, FALSE) = FALSE")
+ cards.where('COALESCE(cards.inactive, FALSE) = FALSE')
end
# @param [Card] card the new active_card
def active_card=(card)
unless card.class == Card
- raise ArgumentError.new "Pass a card to active_card or else"
+ raise ArgumentError, 'Pass a card to active_card or else'
end
+
Card.transaction do
- active_cards.update_all :inactive => true
+ active_cards.update_all inactive: true
return cards << card
end
end
@@ -188,14 +233,38 @@ class Nonprofit < ActiveRecord::Base
end
def create_active_card(card_data)
- if (card_data[:inactive])
- raise ArgumentError.new "This method is for creating active cards only"
+ if card_data[:inactive]
+ raise ArgumentError, 'This method is for creating active cards only'
end
- active_cards.update_all :inactive => true
- return cards.create(card_data)
+
+ active_cards.update_all inactive: true
+ cards.create(card_data)
end
def currency_symbol
- Settings.intntl.all_currencies.find{|i| i.abbv.downcase == currency.downcase}&.symbol
+ Settings.intntl.all_currencies.find { |i| i.abbv.casecmp(currency).zero? }&.symbol
end
+
+private
+ def build_admin_role
+ role = user.roles.build(host: self, name: 'nonprofit_admin')
+ role.save!
+ end
+
+ def add_billing_subscription
+ billing_plan = BillingPlan.find(Settings.default_bp.id)
+ b_sub = build_billing_subscription(billing_plan: billing_plan, status: 'active')
+ b_sub.save!
+ end
+
+ def user_registerable_as_admin
+ if user && user.roles.nonprofit_admins.any?
+ errors.add(:user_id, "cannot already be an admin for a nonprofit.")
+ end
+ end
+
+ def user_is_valid
+ (user && user.is_a?(User)) || errors.add(:user_id, "is not a valid user")
+ end
+
end
diff --git a/app/models/nonprofit_account.rb b/app/models/nonprofit_account.rb
index a3bff211..c30938dd 100644
--- a/app/models/nonprofit_account.rb
+++ b/app/models/nonprofit_account.rb
@@ -1,13 +1,12 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class NonprofitAccount < ActiveRecord::Base
+class NonprofitAccount < ApplicationRecord
+ # :stripe_account_id, #str
+ # :nonprofit, :nonprofit_id #int
- attr_accessible \
- :stripe_account_id, #str
- :nonprofit, :nonprofit_id #int
-
- belongs_to :nonprofit
-
- validates :nonprofit, presence: true
- validates :stripe_account_id, presence: true
+ belongs_to :nonprofit
+ validates :nonprofit, presence: true
+ validates :stripe_account_id, presence: true
end
diff --git a/app/models/offsite_payment.rb b/app/models/offsite_payment.rb
index 4e4cf03a..12f0606b 100644
--- a/app/models/offsite_payment.rb
+++ b/app/models/offsite_payment.rb
@@ -1,10 +1,13 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class OffsitePayment < ActiveRecord::Base
-
- attr_accessible :gross_amount, :kind, :date, :check_number
- belongs_to :payment, dependent: :destroy
- belongs_to :donation
- belongs_to :nonprofit
- belongs_to :supporter
-
+class OffsitePayment < ApplicationRecord
+# :gross_amount,
+# :kind,
+# :date,
+# :check_number
+ belongs_to :payment, dependent: :destroy
+ belongs_to :donation
+ belongs_to :nonprofit
+ belongs_to :supporter
end
diff --git a/app/models/payment.rb b/app/models/payment.rb
index e916a588..17214de7 100644
--- a/app/models/payment.rb
+++ b/app/models/payment.rb
@@ -1,29 +1,28 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
# A payment represents the event where a nonprofit receives money from a supporter
# If connected to a charge, this represents money potentially debited to the nonprofit's account
# If connected to an offsite_payment, this is money the nonprofit is recording for convenience.
-class Payment < ActiveRecord::Base
-
- attr_accessible \
- :towards,
- :gross_amount,
- :refund_total,
- :fee_total,
- :kind,
- :date
-
- belongs_to :supporter
- belongs_to :nonprofit
- has_one :charge
- has_one :offsite_payment
- has_one :refund
- has_one :dispute
- belongs_to :donation
- has_many :tickets
- has_one :campaign, through: :donation
- has_many :events, through: :tickets
- has_many :payment_payouts
- has_many :charges
+class Payment < ApplicationRecord
+ # :towards,
+ # :gross_amount,
+ # :refund_total,
+ # :fee_total,
+ # :kind,
+ # :date
+ belongs_to :supporter
+ belongs_to :nonprofit
+ has_one :charge
+ has_one :offsite_payment
+ has_one :refund
+ has_one :dispute
+ belongs_to :donation
+ has_many :tickets
+ has_one :campaign, through: :donation
+ has_many :events, through: :tickets
+ has_many :payment_payouts
+ has_many :charges
end
diff --git a/app/models/payment_import.rb b/app/models/payment_import.rb
index ebe96e11..244c9e69 100644
--- a/app/models/payment_import.rb
+++ b/app/models/payment_import.rb
@@ -1,6 +1,9 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class PaymentImport < ActiveRecord::Base
- attr_accessible :nonprofit, :user
+class PaymentImport < ApplicationRecord
+ # :nonprofit,
+ # :user
has_and_belongs_to_many :donations
belongs_to :nonprofit
belongs_to :user
diff --git a/app/models/payment_payout.rb b/app/models/payment_payout.rb
index a7a840d1..c817f63e 100644
--- a/app/models/payment_payout.rb
+++ b/app/models/payment_payout.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
# charge_payouts are a join table between charges and payouts
#
@@ -11,19 +13,16 @@
# It's also nice to keep a historical records of fees for individual donations
# since our fees will continue to change as our transaction volume increases
-class PaymentPayout < ActiveRecord::Base
+class PaymentPayout < ApplicationRecord
+ # :payment_id, :payment,
+ # :charge_id, :charge, # deprecated
+ # :payout_id, :payout,
+ # :total_fees # int (cents)
- attr_accessible \
- :payment_id, :payment,
- :charge_id, :charge, # deprecated
- :payout_id, :payout,
- :total_fees # int (cents)
+ belongs_to :charge # deprecated
+ belongs_to :payment
+ belongs_to :payout
- belongs_to :charge # deprecated
- belongs_to :payment
- belongs_to :payout
-
- validates :payment, presence: true
- validates :payout, presence: true
+ validates :payment, presence: true
+ validates :payout, presence: true
end
-
diff --git a/app/models/payout.rb b/app/models/payout.rb
index aa53c033..e5911cc6 100644
--- a/app/models/payout.rb
+++ b/app/models/payout.rb
@@ -1,57 +1,54 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
# Payouts record a credit of the total pending balance on a nonprofit's account
# to their bank account or debit card
#
# These are tied to Stripe transfers
-class Payout < ActiveRecord::Base
+class Payout < ApplicationRecord
+ # :scheduled, # bool (whether this was made automatically at the beginning of the month)
+ # :count, # int (number of donations for this payout)
+ # :ach_fee, # int (in cents, the total fee for the payout itself)
+ # :gross_amount, # int (in cents, total amount before fees)
+ # :fee_total, # int (in cents, total amount of fees)
+ # :net_amount, # int (in cents, total amount after fees for this payout)
+ # :email, # str (cache of user email who issued this)
+ # :user_ip, # str (ip address of the user who made this payout)
+ # :status, # str ('pending', 'paid', 'canceled', or 'failed')
+ # :failure_message, # str
+ # :bank_name, # str: cache of the nonprofit's bank name
+ # :stripe_transfer_id, # str
+ # :nonprofit_id, :nonprofit
- attr_accessible \
- :scheduled, # bool (whether this was made automatically at the beginning of the month)
- :count, # int (number of donations for this payout)
- :ach_fee, # int (in cents, the total fee for the payout itself)
- :gross_amount, # int (in cents, total amount before fees)
- :fee_total, # int (in cents, total amount of fees)
- :net_amount, # int (in cents, total amount after fees for this payout)
- :email, # str (cache of user email who issued this)
- :user_ip, # str (ip address of the user who made this payout)
- :status, # str ('pending', 'paid', 'canceled', or 'failed')
- :failure_message, # str
- :bank_name, # str: cache of the nonprofit's bank name
- :stripe_transfer_id, # str
- :nonprofit_id, :nonprofit
+ belongs_to :nonprofit
+ has_one :bank_account, through: :nonprofit
+ has_many :payment_payouts
+ has_many :payments, through: :payment_payouts
- belongs_to :nonprofit
- has_one :bank_account, through: :nonprofit
- has_many :payment_payouts
- has_many :payments, through: :payment_payouts
+ validates :stripe_transfer_id, presence: true, uniqueness: true
+ validates :nonprofit, presence: true
+ validates :bank_account, presence: true
+ validates :email, presence: true
+ validates :net_amount, presence: true, numericality: { greater_than: 0 }
+ validate :nonprofit_must_be_vetted, on: :create
+ validate :nonprofit_must_have_identity_verified, on: :create
+ validate :bank_account_must_be_confirmed, on: :create
- validates :stripe_transfer_id, presence: true, uniqueness: true
- validates :nonprofit, presence: true
- validates :bank_account, presence: true
- validates :email, presence: true
- validates :net_amount, presence: true, numericality: {greater_than: 0}
- validate :nonprofit_must_be_vetted, on: :create
- validate :nonprofit_must_have_identity_verified, on: :create
- validate :bank_account_must_be_confirmed, on: :create
+ scope :pending, -> { where(status: 'pending') }
+ scope :paid, -> { where(status: %w[paid succeeded]) }
- scope :pending, -> {where(status: 'pending')}
- scope :paid, -> {where(status: ['paid', 'succeeded'])}
+ def bank_account_must_be_confirmed
+ if bank_account&.pending_verification
+ errors.add(:bank_account, 'must be confirmed via email')
+ end
+ end
+ def nonprofit_must_have_identity_verified
+ errors.add(:nonprofit, 'must be verified') unless nonprofit && nonprofit.verification_status == 'verified'
+ end
- def bank_account_must_be_confirmed
- if self.bank_account && self.bank_account.pending_verification
- self.errors.add(:bank_account, 'must be confirmed via email')
- end
- end
-
- def nonprofit_must_have_identity_verified
- self.errors.add(:nonprofit, "must be verified") unless self.nonprofit && self.nonprofit.verification_status == 'verified'
- end
-
- def nonprofit_must_be_vetted
- self.errors.add(:nonprofit, "must be vetted") unless self.nonprofit && self.nonprofit.vetted
- end
-
+ def nonprofit_must_be_vetted
+ errors.add(:nonprofit, 'must be vetted') unless nonprofit&.vetted
+ end
end
-
diff --git a/app/models/profile.rb b/app/models/profile.rb
index 5ff2f392..e53d5d3a 100755
--- a/app/models/profile.rb
+++ b/app/models/profile.rb
@@ -1,119 +1,115 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class Profile < ActiveRecord::Base
+class Profile < ApplicationRecord
+ include Image::AttachmentExtensions
+ # :registered, # bool
+ # :mini_bio,
+ # :first_name, # str
+ # :last_name, # str
+ # :name,
+ # :phone, # str
+ # :address, # str
+ # :email, # str
+ # :city, # str
+ # :state_code, # str (eg. CA)
+ # :zip_code, # str
+ # :privacy_settings, # text [str]: XXX deprecated
+ # :picture, # str: either their social network pic or a stored pic on S3
+ # :anonymous, # bool: negates all privacy_settings
+ # :city_state,
+ # :user_id
- attr_accessible \
- :registered, # bool
- :mini_bio,
- :first_name, # str
- :last_name, # str
- :name,
- :phone, # str
- :address, # str
- :email, # str
- :city, # str
- :state_code, # str (eg. CA)
- :zip_code, # str
- :privacy_settings, # text [str]: XXX deprecated
- :picture, # str: either their social network pic or a stored pic on S3
- :anonymous, # bool: negates all privacy_settings
- :city_state,
- :user_id
+ validates :email, format: { with: Email::Regex }, allow_blank: true
- validates :email, format: {with: Email::Regex}, allow_blank: true
+ attr_accessor :email, :city_state
- attr_accessor :email, :city_state
+ serialize :privacy_settings, Array
- serialize :privacy_settings, Array
+ has_one_attached :picture
+ has_one_attached_with_sizes(:picture, {normal: 150, medium:100, tiny: 50})
- mount_uploader :picture, ProfileUploader
+ belongs_to :user
+ has_many :activities # Activities this profile has created
+ has_many :supporters
+ has_many :donations
+ has_many :campaigns
+ has_many :events
+ has_many :recurring_donations
+ has_many :comments, as: :host, dependent: :destroy
+ has_many :nonprofits, through: :supporters
+ has_many :activities, dependent: :destroy
+ # has_one :card, as: :holder
- belongs_to :user
- has_many :activities # Activities this profile has created
- has_many :supporters
- has_many :donations
- has_many :campaigns
- has_many :events
- has_many :recurring_donations
- has_many :comments, as: :host, dependent: :destroy
- has_many :nonprofits, through: :supporters
- has_many :activities, dependent: :destroy
-# has_one :card, as: :holder
+ # accepts_nested_attributes_for :card
- #accepts_nested_attributes_for :card
+ scope :non_anon, -> { where(anonymous: [nil, false]) }
- scope :non_anon, -> {where(anonymous: [nil, false])}
+ before_validation(on: :create) do
+ set_defaults
+ self
+ end
- before_validation(on: :create) do
- self.set_defaults
- self
- end
+ def set_defaults
+ self.name ||= user.name if user
+ self.email ||= user.email if user
+ picture.attach(io: File.open(Settings.default.image.profile),
+ filename: "profile-image.png") unless self.picture.attached?
+ if self.name.blank? && first_name.present? && last_name.present?
+ self.name ||= first_name + ' ' + last_name
+ end
+ end
- def set_defaults
- self.name ||= self.user.name if self.user
- self.email ||= self.user.email if self.user
- self.picture ||= self.user.picture if self.user
- if self.name.blank? && self.first_name.present? && self.last_name.present?
- self.name ||= self.first_name + ' ' + self.last_name
- end
- end
+ # Queries
- # Queries
+ def recent_donations(npo_id)
+ donations.valid.order('created_at').where(nonprofit_id: npo_id).take(10)
+ end
- def recent_donations(npo_id)
- self.donations.valid.order("created_at").where(nonprofit_id: npo_id).take(10)
- end
+ # Attrs
- # Attrs
+ def total_given_to(nonprofit)
+ donations.valid.where(nonprofit_id: nonprofit.id).pluck(:amount).sum
+ end
- def total_given_to(nonprofit)
- self.donations.valid.where(nonprofit_id: nonprofit.id).pluck(:amount).sum
- end
+ def monthly_giving(nonprofit_id)
+ donations.where(nonprofit_id: nonprofit_id).map(&:amount).sum
+ end
- def monthly_giving(nonprofit_id)
- self.donations.where(nonprofit_id: nonprofit_id).map(&:amount).sum
- end
+ def monthly_total_giving
+ donations.map(&:amount).sum
+ end
- def monthly_total_giving
- self.donations.map(&:amount).sum
- end
+ def full_name
+ "#{first_name} #{last_name}"
+ end
- def full_name
- "#{self.first_name} #{self.last_name}"
- end
+ def supporter_name
+ self.name.blank? ? 'A Supporter' : self.name
+ end
- def supporter_name
- self.name.blank? ? "A Supporter" : self.name
- end
+ def get_profile_picture(size = :normal)
+ # Can be, in order of precedence: your uploaded photo, facebook picture, or
+ # default image
+ if user.picture
+ return user.get_picture(size)
+ else
+ return picture_url(size)
+ end
- def get_profile_picture(size=:normal)
- # Can be, in order of precedence: your uploaded photo, facebook picture, or
- # default image
- if self.user.picture
- return self.user.get_picture(size)
- else
- return self.picture_url(size)
- end
- # Either does not want photo shown or has none uploaded.
- return Image::DefaultProfileUrl
- end
+ # Either does not want photo shown or has none uploaded.
+ Image::DefaultProfileUrl
+ end
- def url
- Rails.application.routes.url_helpers.profile_path(self)
- end
+ def url
+ Rails.application.routes.url_helpers.profile_path(self)
+ end
- def as_json(options = {})
- h = super(options)
- h[:pic_tiny] = self.get_profile_picture :tiny
- h[:url] = self.url
- h
- end
-
- # Cache setters
-
- def set_caches!
- self.total_raised = self.donations.pluck(:amount).sum
- self.total_recurring = self.recurring_donations.active.pluck(:amount).sum
- self.save!
- end
+ # Cache setters
+ def set_caches!
+ self.total_raised = donations.pluck(:amount).sum
+ self.total_recurring = recurring_donations.active.pluck(:amount).sum
+ save!
+ end
end
diff --git a/app/models/recurring_donation.rb b/app/models/recurring_donation.rb
index 1a088b1e..02c40da6 100644
--- a/app/models/recurring_donation.rb
+++ b/app/models/recurring_donation.rb
@@ -1,26 +1,28 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class RecurringDonation < ActiveRecord::Base
+require 'timespan'
- attr_accessible \
- :amount, # int (cents)
- :active, # bool (whether this recurring donation should still be paid)
- :paydate, # int (fixed date of the month for monthly recurring donations)
- :interval, # int (interval of time, ie the '3' in '3 months')
- :time_unit, # str ('month', 'day', 'week', or 'year')
- :start_date, # date (when to start this recurring donation)
- :end_date, # date (when to deactivate this recurring donation)
- :n_failures, # int (how many times the charge has failed)
- :edit_token, # str / uuid to validate the editing page, linked from their email client
- :cancelled_by, # str email of user/supporter who made the cancellation
- :cancelled_at, # datetime of user/supporter who made the cancellation
- :donation_id, :donation,
- :nonprofit_id, :nonprofit,
- :supporter_id #used because things are messed up in the datamodel
+class RecurringDonation < ApplicationRecord
+ # :amount, # int (cents)
+ # :active, # bool (whether this recurring donation should still be paid)
+ # :paydate, # int (fixed date of the month for monthly recurring donations)
+ # :interval, # int (interval of time, ie the '3' in '3 months')
+ # :time_unit, # str ('month', 'day', 'week', or 'year')
+ # :start_date, # date (when to start this recurring donation)
+ # :end_date, # date (when to deactivate this recurring donation)
+ # :n_failures, # int (how many times the charge has failed)
+ # :edit_token, # str / uuid to validate the editing page, linked from their email client
+ # :cancelled_by, # str email of user/supporter who made the cancellation
+ # :cancelled_at, # datetime of user/supporter who made the cancellation
+ # :donation_id, :donation,
+ # :nonprofit_id, :nonprofit,
+ # :supporter_id #used because things are messed up in the datamodel
- scope :active, -> {where(active: true)}
- scope :inactive, -> {where(active: [false,nil])}
- scope :monthly, -> {where(time_unit: 'month', interval: 1)}
- scope :annual, -> {where(time_unit: 'year', interval: 1)}
+ scope :active, -> { where(active: true) }
+ scope :inactive, -> { where(active: [false, nil]) }
+ scope :monthly, -> { where(time_unit: 'month', interval: 1) }
+ scope :annual, -> { where(time_unit: 'year', interval: 1) }
belongs_to :donation
belongs_to :nonprofit
@@ -28,37 +30,30 @@ class RecurringDonation < ActiveRecord::Base
has_one :card, through: :donation
has_one :supporter, through: :donation
- validates :paydate, numericality: {less_than: 29}, allow_blank: true
+ validates :paydate, numericality: { less_than: 29 }, allow_blank: true
validates :donation_id, presence: true
validates :nonprofit_id, presence: true
validates :start_date, presence: true
- validates :interval, presence: true, numericality: {greater_than: 0}
- validates :time_unit, presence: true, inclusion: {in: Timespan::Units}
+ validates :interval, presence: true, numericality: { greater_than: 0 }
+ validates :time_unit, presence: true, inclusion: { in: Timespan::Units }
validates_associated :donation
def most_recent_charge
- if (self.charges)
- return self.charges.sort_by { |c| c.created_at }.last()
- end
+ charges&.max_by(&:created_at)
end
def most_recent_paid_charge
- if (self.charges)
- return self.charges.find_all {|c| c.paid?}.sort_by { |c| c.created_at }.last()
- end
+ charges&.find_all(&:paid?)&.max_by(&:created_at)
end
def total_given
- if (self.charges)
- return self.charges.find_all(&:paid?).sum(&:amount)
- end
-
+ return charges.find_all(&:paid?).sum(&:amount) if charges
end
# XXX let's make these monthly_totals a query
# Or just push it into the front-end
def self.monthly_total
- self.all.map(&:monthly_total).sum
+ all.map(&:monthly_total).sum
end
def monthly_total
@@ -66,8 +61,7 @@ class RecurringDonation < ActiveRecord::Base
'week' => 4,
'day' => 30,
'year' => 0.0833
- }[self.interval] || 1
- return self.donation.amount * multiple
+ }[interval] || 1
+ donation.amount * multiple
end
-
end
diff --git a/app/models/refund.rb b/app/models/refund.rb
index f7fff991..faed9dff 100644
--- a/app/models/refund.rb
+++ b/app/models/refund.rb
@@ -1,26 +1,23 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class Refund < ActiveRecord::Base
+class Refund < ApplicationRecord
+ Reasons = %i[duplicate fraudulent requested_by_customer].freeze
+ # :amount, # int
+ # :comment, # text
+ # :reason, # str ('duplicate', 'fraudulent', or 'requested_by_customer')
+ # :stripe_refund_id,
+ # :disbursed, # boolean (whether this refund has been counted in a payout)
+ # :failure_message, # str (accessor for storing the Stripe error message)
+ # :user_id, :user, # user who made this refund
+ # :payment_id, :payment, # negative payment that records this refund
+ # :charge_id, :charge
- Reasons = [:duplicate, :fraudulent, :requested_by_customer]
+ attr_accessor :failure_message
- attr_accessible \
- :amount, # int
- :comment, # text
- :reason, # str ('duplicate', 'fraudulent', or 'requested_by_customer')
- :stripe_refund_id,
- :disbursed, # boolean (whether this refund has been counted in a payout)
- :failure_message, # str (accessor for storing the Stripe error message)
- :user_id, :user, # user who made this refund
- :payment_id, :payment, # negative payment that records this refund
- :charge_id, :charge
-
- attr_accessor :failure_message
-
- belongs_to :charge
- belongs_to :payment
-
- scope :not_disbursed, ->{where(disbursed: [nil, false])}
- scope :disbursed, ->{where(disbursed: [true])}
+ belongs_to :charge
+ belongs_to :payment
+ scope :not_disbursed, -> { where(disbursed: [nil, false]) }
+ scope :disbursed, -> { where(disbursed: [true]) }
end
-
diff --git a/app/models/role.rb b/app/models/role.rb
index 2c8401bf..5b3002db 100644
--- a/app/models/role.rb
+++ b/app/models/role.rb
@@ -1,49 +1,56 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class Role < ActiveRecord::Base
+class Role < ApplicationRecord
+ Names = [
+ :super_admin, # global access
+ :super_associate, # global access to everything except bank acct info
+ :nonprofit_admin, # npo scoped access to everything
+ :nonprofit_associate, # npo scoped access to everything except bank acct info
+ :campaign_editor, # fundraising tools, without dashboard access
+ :event_editor # //
+ ].freeze
- Names = [
- :super_admin, # global access
- :super_associate, # global access to everything except bank acct info
- :nonprofit_admin, # npo scoped access to everything
- :nonprofit_associate, # npo scoped access to everything except bank acct info
- :campaign_editor, # fundraising tools, without dashboard access
- :event_editor # //
- ]
+ # :name,
+ # :user_id, :user,
+ # :host, :host_id, :host_type # nil, "Nonprofit", "Campaign", "Event"
- attr_accessible \
- :name,
- :user_id, :user,
- :host, :host_id, :host_type # nil, "Nonprofit", "Campaign", "Event"
+ belongs_to :user
+ belongs_to :host, polymorphic: true
- belongs_to :user
- belongs_to :host, polymorphic: true
+ scope :super_admins, -> { where(name: :super_admin) }
+ scope :super_associate, -> { where(name: :super_associate) }
+ scope :nonprofit_admins, -> { where(name: :nonprofit_admin) }
+ scope :nonprofit_personnel, -> { where(name: %i[nonprofit_associate nonprofit_admin]) }
+ scope :campaign_editors, -> { where(name: :campaign_editor) }
+ scope :event_editors, -> { where(name: :event_editor) }
- scope :super_admins, -> {where(name: :super_admin)}
- scope :super_associate, -> {where(name: :super_associate)}
- scope :nonprofit_admins, -> {where(name: :nonprofit_admin)}
- scope :nonprofit_personnel, -> {where(name: [:nonprofit_associate, :nonprofit_admin])}
- scope :campaign_editors, -> {where(name: :campaign_editor)}
- scope :event_editors, -> {where(name: :event_editor)}
-
- validates :user, presence: true
- validates :name, inclusion: {in: Names}
- validates :host, presence: true, unless: [:super_admin?, :super_associate?]
-
- def name; super.to_sym; end
- def super_admin?; name == :super_admin; end
- def super_associate?; name == :super_associate; end
-
- def self.create_for_nonprofit(role_name, email, nonprofit)
- user = User.find_or_create_with_email(email)
- role = Role.create(user: user, name: role_name, host: nonprofit)
- return role unless role.valid?
- if user.confirmed?
- NonprofitAdminMailer.delay.existing_invite(role)
- else
- NonprofitAdminMailer.delay.new_invite(role, user.make_confirmation_token!)
- end
- return role
- end
+ validates :user, presence: true
+ validates :name, inclusion: { in: Names }
+ validates :host, presence: true, unless: %i[super_admin? super_associate?]
+ def name
+ super.to_sym
end
+ def super_admin?
+ name == :super_admin
+end
+
+ def super_associate?
+ name == :super_associate
+end
+
+ def self.create_for_nonprofit(role_name, email, nonprofit)
+ user = User.find_or_create_with_email(email)
+ role = Role.create(user: user, name: role_name, host: nonprofit)
+ return role unless role.valid?
+
+ if user.confirmed?
+ RoleAddedJob.perform_later role
+ else
+ UserInviteCreateJob.perform_later role, user.make_confirmation_token!
+ end
+ role
+ end
+end
diff --git a/app/models/source_token.rb b/app/models/source_token.rb
index 2d785ce1..75e02055 100644
--- a/app/models/source_token.rb
+++ b/app/models/source_token.rb
@@ -1,7 +1,12 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class SourceToken < ActiveRecord::Base
+class SourceToken < ApplicationRecord
self.primary_key = :token
- attr_accessible :expiration, :token, :max_uses, :total_uses
- belongs_to :tokenizable, :polymorphic => true
+ # :expiration,
+ # :token,
+ # :max_uses,
+ # :total_uses
+ belongs_to :tokenizable, polymorphic: true
belongs_to :event
end
diff --git a/app/models/supporter.rb b/app/models/supporter.rb
index 8d5a89de..8b115218 100644
--- a/app/models/supporter.rb
+++ b/app/models/supporter.rb
@@ -1,33 +1,33 @@
-# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class Supporter < ActiveRecord::Base
+# frozen_string_literal: true
- attr_accessible \
- :search_vectors,
- :profile_id, :profile,
- :nonprofit_id, :nonprofit,
- :full_contact_info, :full_contact_info_id,
- :import_id, :import,
- :name,
- :first_name,
- :last_name,
- :email,
- :address,
- :city,
- :state_code,
- :country,
- :phone,
- :organization,
- :latitude,
- :locale,
- :longitude,
- :zip_code,
- :total_raised,
- :notes,
- :fields,
- :anonymous,
- :deleted, # bool (flag for soft delete)
- :email_unsubscribe_uuid, #string
- :is_unsubscribed_from_emails #bool
+# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
+class Supporter < ApplicationRecord
+ # :search_vectors,
+ # :profile_id, :profile,
+ # :nonprofit_id, :nonprofit,
+ # :full_contact_info, :full_contact_info_id,
+ # :import_id, :import,
+ # :name,
+ # :first_name,
+ # :last_name,
+ # :email,
+ # :address,
+ # :city,
+ # :state_code,
+ # :country,
+ # :phone,
+ # :organization,
+ # :latitude,
+ # :locale,
+ # :longitude,
+ # :zip_code,
+ # :total_raised,
+ # :notes,
+ # :fields,
+ # :anonymous,
+ # :deleted, # bool (flag for soft delete)
+ # :email_unsubscribe_uuid, #string
+ # :is_unsubscribed_from_emails #bool
belongs_to :profile
belongs_to :nonprofit
@@ -48,10 +48,10 @@ class Supporter < ActiveRecord::Base
has_many :tag_masters, through: :tag_joins
has_many :custom_field_joins, dependent: :destroy
has_many :custom_field_masters, through: :custom_field_joins
- belongs_to :merged_into, class_name: 'Supporter', :foreign_key => 'merged_into'
+ belongs_to :merged_into, class_name: 'Supporter', foreign_key: 'merged_into'
- validates :nonprofit, :presence => true
- scope :not_deleted, -> {where(deleted: false)}
+ validates :nonprofit, presence: true
+ scope :not_deleted, -> { where(deleted: false) }
geocoded_by :full_address
reverse_geocoded_by :latitude, :longitude do |obj, results|
@@ -65,22 +65,21 @@ class Supporter < ActiveRecord::Base
end
end
- def profile_picture size=:normal
- return unless self.profile
- self.profile.get_profile_picture(size)
- end
+ def profile_picture(size = :normal)
+ return unless profile
+ profile.get_profile_picture(size)
+ end
def as_json(options = {})
h = super(options)
- h[:pic_tiny] = self.profile_picture(:tiny)
- h[:pic_normal] = self.profile_picture(:normal)
- h[:url] = self.profile && Rails.application.routes.url_helpers.profile_path(self.profile)
- return h
+ h[:pic_tiny] = profile_picture(:tiny)
+ h[:pic_normal] = profile_picture(:normal)
+ h[:url] = profile && Rails.application.routes.url_helpers.profile_path(profile)
+ h
end
def full_address
- Format::Address.full_address(self.address, self.city, self.state_code)
+ Format::Address.full_address(address, city, state_code)
end
-
end
diff --git a/app/models/supporter_email.rb b/app/models/supporter_email.rb
index 5ac0d8d9..340afa3a 100644
--- a/app/models/supporter_email.rb
+++ b/app/models/supporter_email.rb
@@ -1,16 +1,17 @@
-# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class SupporterEmail < ActiveRecord::Base
- attr_accessible \
- :to,
- :from,
- :subject,
- :body,
- :recipient_count,
- :supporter_id, :supporter,
- :nonprofit_id,
- :gmail_thread_id
+# frozen_string_literal: true
- belongs_to :supporter
- validates_presence_of :nonprofit_id
- has_many :activities, as: :attachment, dependent: :destroy
+# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
+class SupporterEmail < ApplicationRecord
+ # :to,
+ # :from,
+ # :subject,
+ # :body,
+ # :recipient_count,
+ # :supporter_id, :supporter,
+ # :nonprofit_id,
+ # :gmail_thread_id
+
+ belongs_to :supporter
+ validates_presence_of :nonprofit_id
+ has_many :activities, as: :attachment, dependent: :destroy
end
diff --git a/app/models/supporter_note.rb b/app/models/supporter_note.rb
index dd920f07..cbeeaea9 100644
--- a/app/models/supporter_note.rb
+++ b/app/models/supporter_note.rb
@@ -1,14 +1,13 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class SupporterNote < ActiveRecord::Base
+class SupporterNote < ApplicationRecord
+ # :content,
+ # :supporter_id, :supporter
- attr_accessible \
- :content,
- :supporter_id, :supporter
+ belongs_to :supporter
+ has_many :activities, as: :attachment, dependent: :destroy
- belongs_to :supporter
- has_many :activities, as: :attachment, dependent: :destroy
-
- validates :content, length: {minimum: 1}
- validates :supporter_id, presence: true
+ validates :content, length: { minimum: 1 }
+ validates :supporter_id, presence: true
end
-
diff --git a/app/models/tag_join.rb b/app/models/tag_join.rb
index 5f0e402a..9cdbb154 100644
--- a/app/models/tag_join.rb
+++ b/app/models/tag_join.rb
@@ -1,24 +1,22 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class TagJoin < ActiveRecord::Base
+class TagJoin < ApplicationRecord
+ # :supporter, :supporter_id,
+ # :tag_master, :tag_master_id
- attr_accessible \
- :supporter, :supporter_id,
- :tag_master, :tag_master_id
+ validates :tag_master, presence: true
- validates :tag_master, presence: true
-
- belongs_to :tag_master
- belongs_to :supporter
-
- def name; self.tag_master.name; end
-
- def self.create_with_name(nonprofit, h)
- tm = nonprofit.tag_masters.find_by_name(h['name'])
- if tm.nil?
- tm = nonprofit.tag_masters.create(name: h['name'])
- end
- self.create tag_master: tm, supporter_id: h['supporter_id']
- end
+ belongs_to :tag_master
+ belongs_to :supporter
+ def name
+ tag_master.name
end
+ def self.create_with_name(nonprofit, h)
+ tm = nonprofit.tag_masters.find_by_name(h['name'])
+ tm = nonprofit.tag_masters.create(name: h['name']) if tm.nil?
+ create tag_master: tm, supporter_id: h['supporter_id']
+ end
+end
diff --git a/app/models/tag_master.rb b/app/models/tag_master.rb
index 6e9f0ffd..efca9eea 100644
--- a/app/models/tag_master.rb
+++ b/app/models/tag_master.rb
@@ -1,25 +1,24 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class TagMaster < ActiveRecord::Base
+class TagMaster < ApplicationRecord
+ # :nonprofit, :nonprofit_id,
+ # :name,
+ # :deleted,
+ # :created_at
- attr_accessible \
- :nonprofit, :nonprofit_id,
- :name,
- :deleted,
- :created_at
+ validates :name, presence: true
+ validate :no_dupes, on: :create
- validates :name, presence: true
- validate :no_dupes, on: :create
+ belongs_to :nonprofit
+ has_many :tag_joins, dependent: :destroy
+ has_one :email_list
- belongs_to :nonprofit
- has_many :tag_joins, dependent: :destroy
- has_one :email_list
+ scope :not_deleted, -> { where(deleted: [nil, false]) }
- scope :not_deleted, ->{where(deleted: [nil,false])}
-
- def no_dupes
- return self if nonprofit.nil?
- errors.add(:base, "Duplicate tag") if nonprofit.tag_masters.not_deleted.where(name: name).any?
- end
+ def no_dupes
+ return self if nonprofit.nil?
+ errors.add(:base, 'Duplicate tag') if nonprofit.tag_masters.not_deleted.where(name: name).any?
+ end
end
-
diff --git a/app/models/ticket.rb b/app/models/ticket.rb
index e805ad89..0a19bc09 100644
--- a/app/models/ticket.rb
+++ b/app/models/ticket.rb
@@ -1,21 +1,24 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class Ticket < ActiveRecord::Base
-
- attr_accessible :note, :event_discount, :event_discount_id
+class Ticket < ApplicationRecord
+ # :note,
+ # :event_discount,
+ # :event_discount_id
belongs_to :event_discount
- belongs_to :supporter
- belongs_to :profile
- belongs_to :ticket_level
- belongs_to :event
- belongs_to :charge
- belongs_to :card
- belongs_to :payment
- belongs_to :source_token
- has_one :nonprofit, through: :event
- has_many :activities, as: :attachment, dependent: :destroy
+ belongs_to :supporter
+ belongs_to :profile
+ belongs_to :ticket_level
+ belongs_to :event
+ belongs_to :charge
+ belongs_to :card
+ belongs_to :payment
+ belongs_to :source_token
+ has_one :nonprofit, through: :event
+ has_many :activities, as: :attachment, dependent: :destroy
- def related_tickets
- payment.tickets.where('id != ?', self.id)
- end
+ def related_tickets
+ payment.tickets.where('id != ?', id)
+ end
end
diff --git a/app/models/ticket_level.rb b/app/models/ticket_level.rb
index 9d628782..95994901 100644
--- a/app/models/ticket_level.rb
+++ b/app/models/ticket_level.rb
@@ -1,31 +1,30 @@
-# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class TicketLevel < ActiveRecord::Base
+# frozen_string_literal: true
- attr_accessible \
- :amount, #integer
- :amount_dollars, #accessor, string
- :name, #string
- :description, #text
- :quantity, #integer
- :deleted, #bool for soft delete
- :event_id,
- :admin_only, #bool, only admins can create tickets for this level
- :limit, #int: for limiting the number of tickets to be sold
- :order #int: order in which to be displayed
+# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
+class TicketLevel < ApplicationRecord
+ # :amount, #integer
+ # :amount_dollars, #accessor, string
+ # :name, #string
+ # :description, #text
+ # :quantity, #integer
+ # :deleted, #bool for soft delete
+ # :event_id,
+ # :admin_only, #bool, only admins can create tickets for this level
+ # :limit, #int: for limiting the number of tickets to be sold
+ # :order #int: order in which to be displayed
attr_accessor :amount_dollars
has_many :tickets
belongs_to :event
- validates :name, :presence => true
- validates :event_id, :presence => true
+ validates :name, presence: true
+ validates :event_id, presence: true
- scope :not_deleted, ->{where(deleted: [false,nil])}
+ scope :not_deleted, -> { where(deleted: [false, nil]) }
before_validation do
- self.amount = Format::Currency.dollars_to_cents(self.amount_dollars) if self.amount_dollars.present?
- self.amount = 0 if self.amount.nil?
+ self.amount = Format::Currency.dollars_to_cents(amount_dollars) if amount_dollars.present?
+ self.amount = 0 if amount.nil?
end
-
end
diff --git a/app/models/tracking.rb b/app/models/tracking.rb
index d3a175c7..50485c58 100644
--- a/app/models/tracking.rb
+++ b/app/models/tracking.rb
@@ -1,6 +1,11 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class Tracking < ActiveRecord::Base
- attr_accessible :utm_campaign, :utm_content, :utm_medium, :utm_source
+class Tracking < ApplicationRecord
+ # :utm_campaign,
+ # :utm_content,
+ # :utm_medium,
+ # :utm_source
belongs_to :donation
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 32f1e674..397edd83 100755
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1,109 +1,100 @@
+# frozen_string_literal: true
+
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class User < ActiveRecord::Base
+class User < ApplicationRecord
+ # :email, # str: balidated with Devise
+ # :password, # str: hashed with bcrypt
+ # :phone, # str
+ # :location,
+ # :city,
+ # :state_code,
+ # :password_confirmation, # accessor: used on registration
+ # :remember_me, # bool: don't sign user out for a while
+ # :provider, # str: OAuth provider
+ # :uid, # str: OAuth user ID
+ # :pending_password, # bool: User registered with oauth and did not set a password
+ # :name, # str: created with oauth
+ # :auto_generated, # bool: flag whether a password was auto-generated for this account
+ # :referer, # str: ID of the user who referred this account
+ # :latitude,
+ # :longitude,
+ # :reset_password_token,
+ # :reset_password_sent_at,
+ # :picture, # str: url for fb or twitter pic
+ # :current_password, # accessor: for updating pass
+ # :profile_attributes,
+ # :phone
- attr_accessible \
- :email, # str: balidated with Devise
- :password, # str: hashed with bcrypt
- :phone, # str
- :location,
- :city,
- :state_code,
- :password_confirmation, # accessor: used on registration
- :remember_me, # bool: don't sign user out for a while
- :provider, # str: OAuth provider
- :uid, # str: OAuth user ID
- :pending_password, # bool: User registered with oauth and did not set a password
- :name, # str: created with oauth
- :auto_generated, # bool: flag whether a password was auto-generated for this account
- :referer, # str: ID of the user who referred this account
- :latitude,
- :longitude,
- :reset_password_token,
- :reset_password_sent_at,
- :picture, # str: url for fb or twitter pic
- :current_password, # accessor: for updating pass
- :profile_attributes,
- :phone
+ geocoded_by :location
- geocoded_by :location
+ devise :async, :database_authenticatable, :registerable, :confirmable, :recoverable, :rememberable, :trackable, :validatable
- devise :async, :database_authenticatable, :registerable, :confirmable, :recoverable, :rememberable, :trackable, :validatable
+ attr_accessor :offsite_donation_id, :current_password
- attr_accessor :offsite_donation_id, :current_password
+ validates :email,
+ presence: true,
+ uniqueness: { case_sensitive: false },
+ format: { with: Email::Regex }
- validates :email,
- presence: true,
- uniqueness: {case_sensitive: false},
- format: {with: Email::Regex}
-
- has_many :donations, through: :profile
- has_many :roles, dependent: :destroy
- has_one :profile, dependent: :destroy
- has_many :imports
+ has_many :donations, through: :profile
+ has_many :roles, dependent: :destroy
+ has_one :profile, dependent: :destroy
+ has_many :imports
has_many :email_settings
- accepts_nested_attributes_for :profile
+ accepts_nested_attributes_for :profile
- before_validation(on: :create) do
- self.password = Devise.friendly_token.first(8) if self.auto_generated
- self.build_profile if self.profile.nil?
- self
- end
+ before_validation(on: :create) do
+ self.password = Devise.friendly_token.first(8) if auto_generated
+ build_profile if profile.nil?
+ self
+ end
# This creates the user in the normal way, but also sends the devise email confirmation email, which we don't want to send to np admins or anyone else
def self.register_donor!(params)
u = User.create!(params)
u.send_confirmation_instructions
- return u
- end
+ u
+ end
def self.find_or_create_with_email(em)
- user = self.where("lower(email) = ?", em.downcase).first
+ user = where('lower(email) = ?', em.downcase).first
return user if user.present?
+
User.create!(email: em, auto_generated: true)
end
- def profile_picture(size)
- self.profile.picture_url(size)
- end
+ def profile_picture(size)
+ profile.picture_url(size)
+ end
+ # Required by Devise for Omniauth
+ # https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview
+ def self.new_with_session(params, session)
+ super.tap do |user|
+ if data = session['devise.facebook_data'] && session['devise.facebook_data']['extra']['raw_info']
+ user.email = data['email'] if user.email.blank?
+ end
+ end
+ end
- # Required by Devise for Omniauth
- # https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview
- def self.new_with_session(params, session)
- super.tap do |user|
- if data = session['devise.facebook_data'] && session['devise.facebook_data']['extra']['raw_info']
- user.email = data['email'] if user.email.blank?
- end
- end
- end
-
- # Don't require confirmation for new users -- they can still donate without confirmation
- # https://github.com/plataformatec/devise/wiki/How-To:-Override-confirmations-so-users-can-pick-their-own-passwords-as-part-of-confirmation-activation
- def confirmation_required?
- false
- end
-
- def as_json(options={})
- h = super(options)
- h[:unconfirmed_email] = self.unconfirmed_email
- h[:confirmed] = self.confirmed?
- h[:profile] = self.profile.as_json
- h
- end
+ # Don't require confirmation for new users -- they can still donate without confirmation
+ # https://github.com/plataformatec/devise/wiki/How-To:-Override-confirmations-so-users-can-pick-their-own-passwords-as-part-of-confirmation-activation
+ def confirmation_required?
+ false
+ end
# This is useful for manually generating a Devise user confirmation token so that we can get the confirmation URL with the correct token from anywhere
def make_confirmation_token!
raw, db = Devise.token_generator.generate(User, :confirmation_token)
self.confirmation_token = db
self.confirmation_sent_at = Time.now
- self.save!
- return raw
+ save!
+ raw
end
- def geocode!
- #self.geocode
- #self.save
- end
-
+ def geocode!
+ # self.geocode
+ # self.save
+ end
end
diff --git a/app/uploaders/campaign_background_image_uploader.rb b/app/uploaders/campaign_background_image_uploader.rb
deleted file mode 100644
index 57b6c6cb..00000000
--- a/app/uploaders/campaign_background_image_uploader.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-# encoding: utf-8
-
-class CampaignBackgroundImageUploader < CarrierWave::Uploader::Base
-
- include CarrierWave::MiniMagick
-
-
- def store_dir
- "uploads/campaigns/#{mounted_as}/#{model.id}"
- end
-
- # Create different versions of your uploaded files:
- version :normal do
- process :resize_to_fill => [1000, 600]
- end
-
- def extension_white_list
- %w(jpg jpeg png)
- end
-
- def cache_dir
- "#{Rails.root}/tmp/uploads"
- end
-
-end
diff --git a/app/uploaders/campaign_banner_image_uploader.rb b/app/uploaders/campaign_banner_image_uploader.rb
deleted file mode 100644
index 1c4010d7..00000000
--- a/app/uploaders/campaign_banner_image_uploader.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class CampaignBannerImageUploader < CarrierWave::Uploader::Base
- include CarrierWave::MiniMagick
-
- def store_dir
- "uploads/campaigns/#{mounted_as}/#{model.id}"
- end
-
- def extension_white_list
- %w(jpg jpeg png)
- end
-
- def cache_dir
- "#{Rails.root}/tmp/uploads"
- end
-end
diff --git a/app/uploaders/campaign_main_image_uploader.rb b/app/uploaders/campaign_main_image_uploader.rb
deleted file mode 100644
index bcf66cf1..00000000
--- a/app/uploaders/campaign_main_image_uploader.rb
+++ /dev/null
@@ -1,56 +0,0 @@
-# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class CampaignMainImageUploader < CarrierWave::Uploader::Base
-
- # Include RMagick or MiniMagick support:
- # include CarrierWave::RMagick
- include CarrierWave::MiniMagick
-
- # Include the Sprockets helpers for Rails 3.1+ asset pipeline compatibility:
- # include Sprockets::Helpers::RailsHelper
- # include Sprockets::Helpers::IsolatedHelper
-
- # Override the directory where uploaded files will be stored.
- # This is a sensible default for uploaders that are meant to be mounted:
- def store_dir
- "uploads/campaigns/#{mounted_as}/#{model.id}"
- end
-
- # Provide a default URL as a default if there hasn't been a file uploaded:
- def default_url
- # For Rails 3.1+ asset pipeline compatibility:
- return Image::DefaultProfileUrl
- end
-
- # Process files as they are uploaded:
- # process :scale => [200, 300]
- #
- # def scale(width, height)
- # # do something
- # end
-
- # Create different versions of your uploaded files:
- version :normal do
- process :resize_to_fill => [524, 360]
- end
-
- version :thumb do
- process :resize_to_fill => [180, 150]
- end
-
- # Add a white list of extensions which are allowed to be uploaded.
- # For images you might use something like this:
- def extension_white_list
- %w(jpg jpeg png)
- end
-
- # Override the filename of the uploaded files:
- # Avoid using model.id or version_name here, see uploader/store.rb for details.
- # def filename
- # "something.jpg" if original_filename
- # end
-
- def cache_dir
- "#{Rails.root}/tmp/uploads"
- end
-
-end
diff --git a/app/uploaders/event_main_image_uploader.rb b/app/uploaders/event_main_image_uploader.rb
deleted file mode 100644
index 6afc1216..00000000
--- a/app/uploaders/event_main_image_uploader.rb
+++ /dev/null
@@ -1,56 +0,0 @@
-# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-class EventMainImageUploader < CarrierWave::Uploader::Base
-
- # Include RMagick or MiniMagick support:
- # include CarrierWave::RMagick
- include CarrierWave::MiniMagick
-
- # Include the Sprockets helpers for Rails 3.1+ asset pipeline compatibility:
- # include Sprockets::Helpers::RailsHelper
- # include Sprockets::Helpers::IsolatedHelper
-
- # Override the directory where uploaded files will be stored.
- # This is a sensible default for uploaders that are meant to be mounted:
- def store_dir
- "uploads/events/#{mounted_as}/#{model.id}"
- end
-
- # Provide a default URL as a default if there hasn't been a file uploaded:
- def default_url
- # For Rails 3.1+ asset pipeline compatibility:
- return Image::DefaultProfileUrl
- end
-
- # Process files as they are uploaded:
- # process :scale => [200, 300]
- #
- # def scale(width, height)
- # # do something
- # end
-
- # Create different versions of your uploaded files:
- version :normal do
- process :resize_to_fill => [400, 400]
- end
-
- version :thumb do
- process :resize_to_fill => [100,100]
- end
-
- # Add a white list of extensions which are allowed to be uploaded.
- # For images you might use something like this:
- def extension_white_list
- %w(jpg jpeg png)
- end
-
- # Override the filename of the uploaded files:
- # Avoid using model.id or version_name here, see uploader/store.rb for details.
- # def filename
- # "something.jpg" if original_filename
- # end
-
- def cache_dir
- "#{Rails.root}/tmp/uploads"
- end
-
-end
diff --git a/app/uploaders/nonprofit_logo_uploader.rb b/app/uploaders/nonprofit_logo_uploader.rb
deleted file mode 100644
index c068b73c..00000000
--- a/app/uploaders/nonprofit_logo_uploader.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-# encoding: utf-8
-
-class NonprofitLogoUploader < CarrierWave::Uploader::Base
-
- # Include RMagick or MiniMagick support:
- # include CarrierWave::RMagick
- include CarrierWave::MiniMagick
-
- # Include the Sprockets helpers for Rails 3.1+ asset pipeline compatibility:
- # include Sprockets::Helpers::RailsHelper
- # include Sprockets::Helpers::IsolatedHelper
-
- # Override the directory where uploaded files will be stored.
- # This is a sensible default for uploaders that are meant to be mounted:
- def store_dir
- "uploads/npo/#{mounted_as}/#{model.id}"
- end
-
- # Provide a default URL as a default if there hasn't been a file uploaded:
- def default_url
- # For Rails 3.1+ asset pipeline compatibility:
- return Image::DefaultProfileUrl
- end
-
- # Create different versions of your uploaded files:
- version :large do
- process :resize_to_fit => [180, 180]
- end
- version :normal do
- process :resize_to_fit => [100, 100]
- end
- version :small do
- process :resize_to_fit => [30, 30]
- end
-
- def extension_white_list
- %w(jpg jpeg png gif)
- end
-
- # Override the filename of the uploaded files:
- # Avoid using model.id or version_name here, see uploader/store.rb for details.
- # def filename
- # "something.jpg" if original_filename
- # end
-
- def cache_dir
- "#{Rails.root}/tmp/uploads"
- end
-
-end
diff --git a/app/uploaders/profile_uploader.rb b/app/uploaders/profile_uploader.rb
deleted file mode 100644
index ec911fd4..00000000
--- a/app/uploaders/profile_uploader.rb
+++ /dev/null
@@ -1,60 +0,0 @@
-# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
-# encoding: utf-8
-
-class ProfileUploader < CarrierWave::Uploader::Base
-
- # Include RMagick or MiniMagick support:
- # include CarrierWave::RMagick
- include CarrierWave::MiniMagick
-
- # Include the Sprockets helpers for Rails 3.1+ asset pipeline compatibility:
- # include Sprockets::Helpers::RailsHelper
- # include Sprockets::Helpers::IsolatedHelper
-
- # Override the directory where uploaded files will be stored.
- # This is a sensible default for uploaders that are meant to be mounted:
- def store_dir
- "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
- end
-
- # Provide a default URL as a default if there hasn't been a file uploaded:
- def default_url
- # For Rails 3.1+ asset pipeline compatibility:
- return Image::DefaultProfileUrl
- end
-
- # Process files as they are uploaded:
- # process :scale => [200, 300]
- #
- # def scale(width, height)
- # # do something
- # end
-
- # Create different versions of your uploaded files:
- version :normal do
- process :resize_to_fill => [150, 150]
- end
- version :medium do
- process :resize_to_fill => [100, 100]
- end
- version :tiny do
- process :resize_to_fill => [50, 50]
- end
-
- # Add a white list of extensions which are allowed to be uploaded.
- # For images you might use something like this:
- def extension_white_list
- %w(jpg jpeg png)
- end
-
- # Override the filename of the uploaded files:
- # Avoid using model.id or version_name here, see uploader/store.rb for details.
- # def filename
- # "something.jpg" if original_filename
- # end
-
- def cache_dir
- "#{Rails.root}/tmp/uploads"
- end
-
-end
diff --git a/app/views/api/nonprofits/create.json.jbuilder b/app/views/api/nonprofits/create.json.jbuilder
new file mode 100644
index 00000000..388e5ef7
--- /dev/null
+++ b/app/views/api/nonprofits/create.json.jbuilder
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
+json.id @nonprofit.id
+json.name @nonprofit.name
+json.city @nonprofit.city
+json.state_code @nonprofit.state_code
+json.zip_code @nonprofit.zip_code
+json.state_code_slug @nonprofit.state_code_slug
+json.city_slug @nonprofit.city_slug
+json.slug @nonprofit.slug
+json.email @nonprofit.email
+json.website @nonprofit.website
+json.phone @nonprofit.phone
+
+json.urls do
+ json.plain_url nonprofit_url(@nonprofit)
+ json.slug_url nonprofit_slug_url(@nonprofit)
+end
\ No newline at end of file
diff --git a/app/views/app_data/_nonprofit.jbuilder b/app/views/app_data/_nonprofit.jbuilder
new file mode 100644
index 00000000..9580e4b9
--- /dev/null
+++ b/app/views/app_data/_nonprofit.jbuilder
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
+json.extract! nonprofit, :id, :name, #basics
+ :brand_color, :brand_font, :tagline, #brand
+ :zip_code, :state_code, :city, :latitude, :longitude, #location
+ :slug, :state_code_slug, :city_slug, #slugs
+ :no_anon #options
+json.url nonprofit_path(nonprofit)
+json.logo do
+ json.normal url_for(nonprofit.logo_by_size(:normal))
+end
\ No newline at end of file
diff --git a/app/views/app_data/_profile.jbuilder b/app/views/app_data/_profile.jbuilder
new file mode 100644
index 00000000..90db070e
--- /dev/null
+++ b/app/views/app_data/_profile.jbuilder
@@ -0,0 +1,6 @@
+# frozen_string_literal: true
+
+# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
+json.extract! profile, :id, :name, :country, :picture
+json.url profile_path(profile)
+json.pic_tiny url_for(profile.picture_by_size(:tiny)) if profile.picture.attached?
diff --git a/app/views/app_data/_user.jbuilder b/app/views/app_data/_user.jbuilder
new file mode 100644
index 00000000..a492df98
--- /dev/null
+++ b/app/views/app_data/_user.jbuilder
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
+json.extract! user, :id, :created_at, :updated_at, :email
+json.unconfirmed_email user.unconfirmed_email
+json.confirmed user.confirmed?
+
+json.partial! 'app_data/profile', profile: user.profile
diff --git a/app/views/campaigns/_campaign_media.html.erb b/app/views/campaigns/_campaign_media.html.erb
index afb4d256..ed2cf79c 100644
--- a/app/views/campaigns/_campaign_media.html.erb
+++ b/app/views/campaigns/_campaign_media.html.erb
@@ -11,7 +11,7 @@