Skip to content
This repository has been archived by the owner on Aug 11, 2024. It is now read-only.

Commit

Permalink
Merge pull request #389 from beabee-communityrm/v0.12.x
Browse files Browse the repository at this point in the history
Merge v0.12.x changes
  • Loading branch information
wpf500 authored Apr 4, 2024
2 parents bdcc9e4 + e0dbcd6 commit 293c8df
Show file tree
Hide file tree
Showing 20 changed files with 133 additions and 49 deletions.
6 changes: 3 additions & 3 deletions src/api/controllers/SignupController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ export class SignupController {
throw new NotFoundError();
}

if (data.firstname || data.lastname) {
joinFlow.joinForm.firstname = data.firstname || null;
joinFlow.joinForm.lastname = data.lastname || null;
// Merge additional data into the join form
if (data.firstname || data.lastname || data.vatNumber) {
Object.assign(joinFlow.joinForm, data);
await getRepository(JoinFlow).save(joinFlow);
}

Expand Down
3 changes: 2 additions & 1 deletion src/api/dto/AddressDto.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Address from "@models/Address";
import { IsDefined, IsOptional, IsString } from "class-validator";

import { Address } from "@type/address";

export class UpdateAddressDto implements Address {
@IsDefined()
@IsString()
Expand Down
12 changes: 11 additions & 1 deletion src/api/dto/SignupFlowDto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ import {
IsString
} from "class-validator";

import { UpdateAddressDto } from "@api/dto/AddressDto";
import { StartContributionDto } from "@api/dto/ContributionDto";
import { CompleteJoinFlowDto } from "@api/dto/JoinFlowDto";
import IsPassword from "@api/validators/IsPassword";
import IsUrl from "@api/validators/IsUrl";

import type JoinForm from "@models/JoinForm";

import { CompleteUrls } from "@type/complete-urls";

export class StartSignupFlowDto implements CompleteUrls {
Expand All @@ -37,12 +40,19 @@ export class StartSignupFlowDto implements CompleteUrls {
contribution?: StartContributionDto;
}

export class CompleteSignupFlowDto extends CompleteJoinFlowDto {
export class CompleteSignupFlowDto
extends CompleteJoinFlowDto
implements Pick<JoinForm, "firstname" | "lastname" | "vatNumber">
{
@IsOptional()
@IsString()
firstname?: string;

@IsOptional()
@IsString()
lastname?: string;

@IsOptional()
@IsString()
vatNumber?: string;
}
6 changes: 3 additions & 3 deletions src/api/transformers/AddressTransformer.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { GetAddressDto } from "@api/dto/AddressDto";

import Address from "@models/Address";
import { TransformPlainToInstance } from "class-transformer";

import { GetAddressDto } from "@api/dto/AddressDto";
import { Address } from "@type/address";

// TODO: make Address into a proper model
class AddressTransformer {
@TransformPlainToInstance(GetAddressDto)
Expand Down
3 changes: 2 additions & 1 deletion src/apps/gift/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import GiftService from "@core/services/GiftService";
import ContactsService from "@core/services/ContactsService";
import OptionsService from "@core/services/OptionsService";

import Address from "@models/Address";
import GiftFlow, { GiftForm } from "@models/GiftFlow";

import { Address } from "@type/address";

import { createGiftSchema, updateGiftAddressSchema } from "./schema.json";

const app = express();
Expand Down
3 changes: 2 additions & 1 deletion src/apps/tools/apps/exports/exports/GiftsExport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { SelectQueryBuilder } from "typeorm";

import { createQueryBuilder } from "@core/database";

import Address from "@models/Address";
import GiftFlow from "@models/GiftFlow";

import { Address } from "@type/address";

import BaseExport, { ExportResult } from "./BaseExport";

function addressFields(address: Address | null) {
Expand Down
2 changes: 1 addition & 1 deletion src/core/providers/payment-flow/GCProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class GCProvider implements PaymentFlowProvider {
log.info("Completed redirect flow " + redirectFlow.id);

return {
paymentMethod: joinFlow.joinForm.paymentMethod,
joinForm: joinFlow.joinForm,
customerId: redirectFlow.links!.customer!,
mandateId: redirectFlow.links!.mandate!
};
Expand Down
7 changes: 4 additions & 3 deletions src/core/providers/payment-flow/StripeProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,13 @@ class StripeProvider implements PaymentFlowProvider {

log.info("Fetched setup intent " + setupIntent.id);

const paymentMethod = setupIntent.payment_method as string;
const siPaymentMethodId = setupIntent.payment_method as string;

return {
paymentMethod: joinFlow.joinForm.paymentMethod,
// paymentMethod: joinFlow.joinForm.paymentMethod,
joinForm: joinFlow.joinForm,
customerId: "", // Not needed
mandateId: paymentMethod
mandateId: siPaymentMethodId
};
}

Expand Down
8 changes: 4 additions & 4 deletions src/core/providers/payment-flow/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { PaymentMethod } from "@beabee/beabee-common";

import Address from "@models/Address";
import JoinFlow from "@models/JoinFlow";
import JoinForm from "@models/JoinForm";

import { Address } from "@type/address";

export interface PaymentFlow {
id: string;
Expand All @@ -20,7 +20,7 @@ export interface PaymentFlowData {
}

export interface CompletedPaymentFlow {
paymentMethod: PaymentMethod;
joinForm: JoinForm;
customerId: string;
mandateId: string;
}
Expand Down
47 changes: 33 additions & 14 deletions src/core/providers/payment/StripeProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,28 +79,47 @@ export default class StripeProvider extends PaymentProvider<StripePaymentData> {
await this.updateData();
}

async updatePaymentMethod(
completedPaymentFlow: CompletedPaymentFlow
): Promise<void> {
async updatePaymentMethod(flow: CompletedPaymentFlow): Promise<void> {
const paymentMethod = await stripe.paymentMethods.retrieve(flow.mandateId);
const address = paymentMethod.billing_details.address;

const customerData: Stripe.CustomerUpdateParams = {
invoice_settings: {
default_payment_method: flow.mandateId
},
address: address
? {
line1: address.line1 || "",
...(address.city && { city: address.city }),
...(address.country && { country: address.country }),
...(address.line2 && { line2: address.line2 }),
...(address.postal_code && { postal_code: address.postal_code }),
...(address.state && { state: address.state })
}
: null
};

if (this.data.customerId) {
log.info("Attach new payment source to " + this.data.customerId);
await stripe.paymentMethods.attach(completedPaymentFlow.mandateId, {
await stripe.paymentMethods.attach(flow.mandateId, {
customer: this.data.customerId
});
await stripe.customers.update(this.data.customerId, {
invoice_settings: {
default_payment_method: completedPaymentFlow.mandateId
}
});
await stripe.customers.update(this.data.customerId, customerData);
} else {
log.info("Create new customer");
const customer = await stripe.customers.create({
email: this.contact.email,
name: `${this.contact.firstname} ${this.contact.lastname}`,
payment_method: completedPaymentFlow.mandateId,
invoice_settings: {
default_payment_method: completedPaymentFlow.mandateId
}
payment_method: flow.mandateId,
...(flow.joinForm.vatNumber && {
tax_id_data: [
{
type: "eu_vat",
value: flow.joinForm.vatNumber
}
]
}),
...customerData
});
this.data.customerId = customer.id;
}
Expand All @@ -110,7 +129,7 @@ export default class StripeProvider extends PaymentProvider<StripePaymentData> {
await stripe.paymentMethods.detach(this.data.mandateId);
}

this.data.mandateId = completedPaymentFlow.mandateId;
this.data.mandateId = flow.mandateId;

await this.updateData();
}
Expand Down
7 changes: 4 additions & 3 deletions src/core/services/GiftService.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
import { ContributionType, NewsletterStatus } from "@beabee/beabee-common";
import muhammara from "muhammara";
import moment from "moment";
import { getRepository } from "typeorm";

import { getRepository } from "@core/database";
import { log as mainLogger } from "@core/logging";
import stripe from "@core/lib/stripe";
import { isDuplicateIndex } from "@core/utils";
import { generateContactCode } from "@core/utils/contact";

import EmailService from "@core/services/EmailService";
import ContactsService from "@core/services/ContactsService";
import OptionsService from "@core/services/OptionsService";

import Address from "@models/Address";
import GiftFlow, { GiftForm } from "@models/GiftFlow";
import ContactRole from "@models/ContactRole";

import config from "@config";
import { generateContactCode } from "@core/utils/contact";

import { Address } from "@type/address";

const log = mainLogger.child({ app: "gift-service" });

Expand Down
5 changes: 2 additions & 3 deletions src/core/services/PaymentFlowService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import ContactsService from "@core/services/ContactsService";
import OptionsService from "@core/services/OptionsService";
import PaymentService from "@core/services/PaymentService";
import ResetSecurityFlowService from "./ResetSecurityFlowService";

import Address from "@models/Address";
import JoinFlow from "@models/JoinFlow";
import JoinForm from "@models/JoinForm";
import Contact from "@models/Contact";
Expand All @@ -29,6 +27,7 @@ import DuplicateEmailError from "@api/errors/DuplicateEmailError";

import { RESET_SECURITY_FLOW_TYPE } from "@enums/reset-security-flow-type";

import { Address } from "@type/address";
import { CompleteUrls } from "@type/complete-urls";

const paymentProviders = {
Expand Down Expand Up @@ -225,7 +224,7 @@ class PaymentFlowService implements PaymentFlowProvider {
completedPaymentFlow: CompletedPaymentFlow
): Promise<CompletedPaymentFlowData> {
return paymentProviders[
completedPaymentFlow.paymentMethod
completedPaymentFlow.joinForm.paymentMethod
].getCompletedPaymentFlowData(completedPaymentFlow);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/services/PaymentService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ class PaymentService {
});

const data = await this.getData(contact);
const newMethod = completedPaymentFlow.paymentMethod;
const newMethod = completedPaymentFlow.joinForm.paymentMethod;
if (data.method !== newMethod) {
log.info(
"Changing payment method, cancelling any previous contribution",
Expand Down
23 changes: 23 additions & 0 deletions src/migrations/1712158796671-AddExtraJoinFormFields.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { MigrationInterface, QueryRunner } from "typeorm";

export class AddExtraJoinFormFields1712158796671 implements MigrationInterface {
name = "AddExtraJoinFormFields1712158796671";

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "join_flow" ADD "joinFormBillingaddress" jsonb`
);
await queryRunner.query(
`ALTER TABLE "join_flow" ADD "joinFormVatnumber" character varying`
);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "join_flow" DROP COLUMN "joinFormVatnumber"`
);
await queryRunner.query(
`ALTER TABLE "join_flow" DROP COLUMN "joinFormBillingaddress"`
);
}
}
19 changes: 19 additions & 0 deletions src/migrations/1712163090314-RemoveJoinFormBillingAddress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { MigrationInterface, QueryRunner } from "typeorm";

export class RemoveJoinFormBillingAddress1712163090314
implements MigrationInterface
{
name = "RemoveJoinFormBillingAddress1712163090314";

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "join_flow" DROP COLUMN "joinFormBillingaddress"`
);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "join_flow" ADD "joinFormBillingaddress" jsonb`
);
}
}
3 changes: 2 additions & 1 deletion src/models/ContactProfile.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { NewsletterStatus } from "@beabee/beabee-common";
import { Column, Entity, JoinColumn, OneToOne, PrimaryColumn } from "typeorm";

import type Address from "./Address";
import type Contact from "./Contact";

import { Address } from "@type/address";

@Entity()
export default class ContactProfile {
@PrimaryColumn()
Expand Down
3 changes: 2 additions & 1 deletion src/models/GiftFlow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import {
PrimaryGeneratedColumn
} from "typeorm";

import type Address from "./Address";
import type Contact from "./Contact";

import { Address } from "@type/address";

export class GiftForm {
@Column()
firstname!: string;
Expand Down
18 changes: 12 additions & 6 deletions src/models/JoinForm.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { ContributionPeriod, PaymentMethod } from "@beabee/beabee-common";
import { Column } from "typeorm";

import { PaymentForm } from "@core/utils";
import Password from "./Password";

import { Address } from "@type/address";

export interface ReferralGiftForm {
referralGift?: string | null;
referralGiftOptions?: Record<string, string> | null;
Expand All @@ -15,12 +18,6 @@ export default class JoinForm implements PaymentForm, ReferralGiftForm {
@Column(() => Password)
password!: Password;

@Column({ type: String, nullable: true })
firstname?: string | null;

@Column({ type: String, nullable: true })
lastname?: string | null;

@Column({ type: "real" })
monthlyAmount!: number;

Expand All @@ -36,6 +33,15 @@ export default class JoinForm implements PaymentForm, ReferralGiftForm {
@Column()
paymentMethod!: PaymentMethod;

@Column({ type: String, nullable: true })
firstname?: string | null;

@Column({ type: String, nullable: true })
lastname?: string | null;

@Column({ type: String, nullable: true })
vatNumber?: string | null;

@Column({ type: String, nullable: true })
referralCode?: string | null;

Expand Down
3 changes: 2 additions & 1 deletion src/tools/database/import-steady.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ import { cleanEmailAddress } from "@core/utils";

import ContactsService from "@core/services/ContactsService";

import Address from "@models/Address";
import Contact from "@models/Contact";
import ContactRole from "@models/ContactRole";

import { Address } from "@type/address";

const headers = [
"first_name",
"last_name",
Expand Down
2 changes: 1 addition & 1 deletion src/models/Address.ts → src/type/address.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export default interface Address {
export interface Address {
line1: string;
line2?: string | undefined;
city: string;
Expand Down

0 comments on commit 293c8df

Please sign in to comment.