feat: payment collection data model (#2343)

* feat: payment collection data model
This commit is contained in:
Carlos R. L. Rodrigues
2022-10-04 15:41:12 -03:00
committed by GitHub
parent 44b774c72c
commit e20f77ac66
11 changed files with 264 additions and 10 deletions

View File

@@ -10,7 +10,6 @@ import middlewares, { transformQuery } from "../../../middlewares"
import { AdminGetOrdersParams } from "./list-orders"
import { FlagRouter } from "../../../../utils/flag-router"
import SalesChannelFeatureFlag from "../../../../loaders/feature-flags/sales-channels"
import OrderEditingFeatureFlag from "../../../../loaders/feature-flags/order-editing"
const route = Router()

View File

@@ -0,0 +1,116 @@
import { MigrationInterface, QueryRunner } from "typeorm"
import OrderEditingFeatureFlag from "../loaders/feature-flags/order-editing"
export const featureFlag = OrderEditingFeatureFlag.key
export class paymentCollection1664880666982 implements MigrationInterface {
name = "paymentCollection1664880666982"
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
CREATE TYPE "PAYMENT_COLLECTION_TYPE_ENUM" AS ENUM ('order_edit');
CREATE TYPE "PAYMENT_COLLECTION_STATUS_ENUM" AS ENUM (
'not_paid', 'awaiting', 'authorized', 'partially_authorized', 'captured',
'partially_captured', 'refunded', 'partially_refunded', 'canceled', 'requires_action'
);
CREATE TABLE IF NOT EXISTS payment_collection
(
id character varying NOT NULL,
created_at timestamp WITH time zone NOT NULL DEFAULT Now(),
updated_at timestamp WITH time zone NOT NULL DEFAULT Now(),
deleted_at timestamp WITH time zone NULL,
type "PAYMENT_COLLECTION_TYPE_ENUM" NOT NULL,
status "PAYMENT_COLLECTION_STATUS_ENUM" NOT NULL,
description text NULL,
amount integer NOT NULL,
authorized_amount integer NULL,
refunded_amount integer NULL,
region_id character varying NOT NULL,
currency_code character varying NOT NULL,
metadata jsonb NULL,
created_by character varying NOT NULL,
CONSTRAINT "PK_payment_collection_id" PRIMARY KEY ("id")
);
CREATE INDEX "IDX_payment_collection_region_id" ON "payment_collection" ("region_id") WHERE deleted_at IS NULL;
CREATE INDEX "IDX_payment_collection_currency_code" ON "payment_collection" ("currency_code") WHERE deleted_at IS NULL;
ALTER TABLE "payment_collection" ADD CONSTRAINT "FK_payment_collection_region_id" FOREIGN KEY ("region_id") REFERENCES "region"("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
CREATE TABLE payment_collection_sessions
(
payment_collection_id CHARACTER VARYING NOT NULL,
payment_session_id CHARACTER VARYING NOT NULL,
CONSTRAINT "PK_payment_collection_sessions" PRIMARY KEY ("payment_collection_id", "payment_session_id")
);
CREATE INDEX "IDX_payment_collection_sessions_payment_collection_id" ON "payment_collection_sessions" ("payment_collection_id");
CREATE INDEX "IDX_payment_collection_sessions_payment_session_id" ON "payment_collection_sessions" ("payment_session_id");
ALTER TABLE "payment_collection_sessions" ADD CONSTRAINT "FK_payment_collection_sessions_payment_collection_id" FOREIGN KEY ("payment_collection_id") REFERENCES "payment_collection"("id") ON DELETE CASCADE ON UPDATE NO ACTION;
ALTER TABLE "payment_collection_sessions" ADD CONSTRAINT "FK_payment_collection_sessions_payment_session_id" FOREIGN KEY ("payment_session_id") REFERENCES "payment_session"("id") ON DELETE CASCADE ON UPDATE NO ACTION;
CREATE TABLE payment_collection_payments
(
payment_collection_id CHARACTER VARYING NOT NULL,
payment_id CHARACTER VARYING NOT NULL,
CONSTRAINT "PK_payment_collection_payments" PRIMARY KEY ("payment_collection_id", "payment_id")
);
CREATE INDEX "IDX_payment_collection_payments_payment_collection_id" ON "payment_collection_payments" ("payment_collection_id");
CREATE INDEX "IDX_payment_collection_payments_payment_id" ON "payment_collection_payments" ("payment_id");
ALTER TABLE "payment_collection_payments" ADD CONSTRAINT "FK_payment_collection_payments_payment_collection_id" FOREIGN KEY ("payment_collection_id") REFERENCES "payment_collection"("id") ON DELETE CASCADE ON UPDATE NO ACTION;
ALTER TABLE "payment_collection_payments" ADD CONSTRAINT "FK_payment_collection_payments_payment_id" FOREIGN KEY ("payment_id") REFERENCES "payment"("id") ON DELETE CASCADE ON UPDATE NO ACTION;
ALTER TABLE order_edit ADD COLUMN payment_collection_id character varying NULL;
CREATE INDEX "IDX_order_edit_payment_collection_id" ON "order_edit" ("payment_collection_id");
ALTER TABLE "order_edit" ADD CONSTRAINT "FK_order_edit_payment_collection_id" FOREIGN KEY ("payment_collection_id") REFERENCES "payment_collection"("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
ALTER TABLE payment_session ADD COLUMN payment_authorized_at timestamp WITH time zone NULL;
`)
// Add missing indexes
await queryRunner.query(`
CREATE INDEX "IDX_order_edit_order_id" ON "order_edit" ("order_id");
CREATE INDEX "IDX_money_amount_currency_code" ON "money_amount" ("currency_code");
CREATE INDEX "IDX_order_currency_code" ON "order" ("currency_code");
CREATE INDEX "IDX_payment_currency_code" ON "payment" ("currency_code");
CREATE INDEX "IDX_region_currency_code" ON "region" ("currency_code");
`)
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
ALTER TABLE payment_collection DROP CONSTRAINT "FK_payment_collection_region_id";
ALTER TABLE payment_collection_sessions DROP CONSTRAINT "FK_payment_collection_sessions_payment_collection_id";
ALTER TABLE payment_collection_sessions DROP CONSTRAINT "FK_payment_collection_sessions_payment_session_id";
ALTER TABLE payment_collection_payments DROP CONSTRAINT "FK_payment_collection_payments_payment_collection_id";
ALTER TABLE payment_collection_payments DROP CONSTRAINT "FK_payment_collection_payments_payment_id";
ALTER TABLE order_edit DROP COLUMN payment_collection_id;
ALTER TABLE payment_session DROP COLUMN payment_authorized_at;
DROP TABLE payment_collection;
DROP TABLE payment_collection_sessions;
DROP TABLE payment_collection_payments;
DROP TYPE "PAYMENT_COLLECTION_TYPE_ENUM";
DROP TYPE "PAYMENT_COLLECTION_STATUS_ENUM";
DROP INDEX "IDX_order_edit_payment_collection_id";
ALTER TABLE order_edit DROP CONSTRAINT "FK_order_edit_payment_collection_id";
`)
await queryRunner.query(`
DROP INDEX "IDX_order_edit_order_id";
DROP INDEX "IDX_money_amount_currency_code";
DROP INDEX "IDX_order_currency_code";
DROP INDEX "IDX_payment_currency_code";
DROP INDEX "IDX_region_currency_code";
`)
}
}

View File

@@ -40,6 +40,7 @@ export * from "./order-item-change"
export * from "./payment"
export * from "./payment-provider"
export * from "./payment-session"
export * from "./payment-collection"
export * from "./price-list"
export * from "./product"
export * from "./product-collection"

View File

@@ -16,6 +16,7 @@ import { generateEntityId } from "../utils/generate-entity-id"
@Entity()
export class MoneyAmount extends SoftDeletableEntity {
@Index()
@Column()
currency_code: string

View File

@@ -2,19 +2,20 @@ import {
AfterLoad,
BeforeInsert,
Column,
Index,
JoinColumn,
ManyToOne,
OneToMany,
OneToOne,
} from "typeorm"
import OrderEditingFeatureFlag from "../loaders/feature-flags/order-editing"
import { FeatureFlagEntity } from "../utils/feature-flag-decorators"
import { resolveDbType } from "../utils/db-aware-column"
import { OrderItemChange } from "./order-item-change"
import { BaseEntity } from "../interfaces"
import { generateEntityId } from "../utils"
import { LineItem } from "./line-item"
import { Order } from "./order"
import { LineItem, Order, OrderItemChange, PaymentCollection } from "."
export enum OrderEditStatus {
CONFIRMED = "confirmed",
@@ -26,6 +27,7 @@ export enum OrderEditStatus {
@FeatureFlagEntity(OrderEditingFeatureFlag.key)
export class OrderEdit extends BaseEntity {
@Index()
@Column()
order_id: string
@@ -74,6 +76,14 @@ export class OrderEdit extends BaseEntity {
@OneToMany(() => LineItem, (lineItem) => lineItem.order_edit)
items: LineItem[]
@Index()
@Column({ nullable: true })
payment_collection_id: string
@OneToOne(() => PaymentCollection)
@JoinColumn({ name: "payment_collection_id" })
payment_collection: PaymentCollection
// Computed
shipping_total: number
discount_total: number

View File

@@ -140,6 +140,7 @@ export class Order extends BaseEntity {
@JoinColumn({ name: "region_id" })
region: Region
@Index()
@Column()
currency_code: string

View File

@@ -0,0 +1,110 @@
import {
BeforeInsert,
Column,
Index,
JoinColumn,
JoinTable,
ManyToMany,
ManyToOne,
} from "typeorm"
import { SoftDeletableEntity } from "../interfaces/models/soft-deletable-entity"
import { DbAwareColumn } from "../utils/db-aware-column"
import { generateEntityId } from "../utils"
import { Currency, Payment, PaymentSession, Region } from "."
import OrderEditingFeatureFlag from "../loaders/feature-flags/order-editing"
import { FeatureFlagEntity } from "../utils/feature-flag-decorators"
export enum PaymentCollectionStatus {
NOT_PAID = "not_paid",
AWAITING = "awaiting",
AUTHORIZED = "authorized",
PARTIALLY_AUTHORIZED = "partially_authorized",
CAPTURED = "captured",
PARTIALLY_CAPTURED = "partially_captured",
REFUNDED = "refunded",
PARTIALLY_REFUNDED = "partially_refunded",
CANCELED = "canceled",
REQUIRES_ACTION = "requires_action",
}
export enum PaymentCollectionType {
ORDER_EDIT = "order_edit",
}
@FeatureFlagEntity(OrderEditingFeatureFlag.key)
export class PaymentCollection extends SoftDeletableEntity {
@DbAwareColumn({ type: "enum", enum: PaymentCollectionType })
type: string
@DbAwareColumn({ type: "enum", enum: PaymentCollectionStatus })
status: string
@Column({ nullable: true })
description: string
@Column({ type: "int" })
amount: number
@Column({ type: "int", nullable: true })
authorized_amount: number
@Column({ type: "int", nullable: true })
refunded_amount: number
@Index()
@Column()
region_id: string
@ManyToOne(() => Region)
@JoinColumn({ name: "region_id" })
region: Region
@Index()
@Column()
currency_code: string
@ManyToOne(() => Currency)
@JoinColumn({ name: "currency_code", referencedColumnName: "code" })
currency: Currency
@ManyToMany(() => PaymentSession)
@JoinTable({
name: "payment_collection_sessions",
joinColumn: {
name: "payment_collection_id",
referencedColumnName: "id",
},
inverseJoinColumn: {
name: "payment_session_id",
referencedColumnName: "id",
},
})
payment_sessions: PaymentSession[]
@ManyToMany(() => Payment)
@JoinTable({
name: "payment_collection_payments",
joinColumn: {
name: "payment_collection_id",
referencedColumnName: "id",
},
inverseJoinColumn: {
name: "payment_id",
referencedColumnName: "id",
},
})
payments: Payment[]
@DbAwareColumn({ type: "jsonb" })
metadata: Record<string, unknown>
@Column()
created_by: string
@BeforeInsert()
private beforeInsert(): void {
this.id = generateEntityId(this.id, "paycol")
}
}

View File

@@ -10,8 +10,10 @@ import {
import { BaseEntity } from "../interfaces"
import { Cart } from "./cart"
import { DbAwareColumn } from "../utils/db-aware-column"
import { DbAwareColumn, resolveDbType } from "../utils/db-aware-column"
import { generateEntityId } from "../utils"
import { FeatureFlagDecorators } from "../utils/feature-flag-decorators"
import OrderEditingFeatureFlag from "../loaders/feature-flags/order-editing"
export enum PaymentSessionStatus {
AUTHORIZED = "authorized",
@@ -49,6 +51,11 @@ export class PaymentSession extends BaseEntity {
@Column({ nullable: true })
idempotency_key: string
@FeatureFlagDecorators(OrderEditingFeatureFlag.key, [
Column({ type: resolveDbType("timestamptz"), nullable: true }),
])
payment_authorized_at: Date
@BeforeInsert()
private beforeInsert(): void {
this.id = generateEntityId(this.id, "ps")

View File

@@ -17,7 +17,10 @@ import { Swap } from "./swap"
import { generateEntityId } from "../utils/generate-entity-id"
@Index(["cart_id"], { where: "canceled_at IS NOT NULL" })
@Index("UniquePaymentActive", ["cart_id"], { where: "canceled_at IS NULL", unique: true, })
@Index("UniquePaymentActive", ["cart_id"], {
where: "canceled_at IS NULL",
unique: true,
})
@Entity()
export class Payment extends BaseEntity {
@Index()
@@ -40,16 +43,14 @@ export class Payment extends BaseEntity {
@Column({ nullable: true })
order_id: string
@ManyToOne(
() => Order,
(order) => order.payments
)
@ManyToOne(() => Order, (order) => order.payments)
@JoinColumn({ name: "order_id" })
order: Order
@Column({ type: "int" })
amount: number
@Index()
@Column()
currency_code: string

View File

@@ -2,6 +2,7 @@ import {
BeforeInsert,
Column,
Entity,
Index,
JoinColumn,
JoinTable,
ManyToMany,
@@ -26,6 +27,7 @@ export class Region extends SoftDeletableEntity {
@Column()
name: string
@Index()
@Column()
currency_code: string

View File

@@ -0,0 +1,6 @@
import { PaymentCollection } from "./../models/payment-collection"
import { EntityRepository, Repository } from "typeorm"
@EntityRepository(PaymentCollection)
// eslint-disable-next-line max-len
export class PaymentCollectionRepository extends Repository<PaymentCollection> {}