rwadurian/backend/services/planting-service/src/pre-planting/domain/aggregates/pre-planting-merge.aggregat...

181 lines
5.4 KiB
TypeScript

import { PrePlantingContractStatus } from '../value-objects/pre-planting-contract-status.enum';
import { DomainEvent } from '../../../domain/events/domain-event.interface';
import { PrePlantingMergedEvent } from '../events/pre-planting-merged.event';
import { PrePlantingContractSignedEvent } from '../events/pre-planting-contract-signed.event';
export interface PrePlantingMergeData {
id?: bigint;
mergeNo: string;
userId: bigint;
accountSequence: string;
sourceOrderNos: string[];
treeCount: number;
provinceCode?: string | null;
cityCode?: string | null;
contractStatus: PrePlantingContractStatus;
contractSignedAt?: Date | null;
miningEnabledAt?: Date | null;
mergedAt?: Date;
}
export class PrePlantingMerge {
private _id: bigint | null;
private readonly _mergeNo: string;
private readonly _userId: bigint;
private readonly _accountSequence: string;
private readonly _sourceOrderNos: string[];
private readonly _treeCount: number;
private _provinceCode: string | null;
private _cityCode: string | null;
private _contractStatus: PrePlantingContractStatus;
private _contractSignedAt: Date | null;
private _miningEnabledAt: Date | null;
private readonly _mergedAt: Date;
private _domainEvents: DomainEvent[] = [];
private constructor(
mergeNo: string,
userId: bigint,
accountSequence: string,
sourceOrderNos: string[],
provinceCode: string | null,
cityCode: string | null,
mergedAt?: Date,
) {
this._id = null;
this._mergeNo = mergeNo;
this._userId = userId;
this._accountSequence = accountSequence;
this._sourceOrderNos = sourceOrderNos;
this._treeCount = 1;
this._provinceCode = provinceCode;
this._cityCode = cityCode;
this._contractStatus = PrePlantingContractStatus.PENDING;
this._contractSignedAt = null;
this._miningEnabledAt = null;
this._mergedAt = mergedAt || new Date();
}
/**
* 创建合并记录
*/
static create(
mergeNo: string,
userId: bigint,
accountSequence: string,
sourceOrderNos: string[],
provinceCode: string,
cityCode: string,
totalTreesMergedAfter: number,
): PrePlantingMerge {
if (sourceOrderNos.length !== 5) {
throw new Error(`合并需要 5 个订单,收到 ${sourceOrderNos.length}`);
}
const merge = new PrePlantingMerge(
mergeNo,
userId,
accountSequence,
sourceOrderNos,
provinceCode,
cityCode,
);
merge._domainEvents.push(
new PrePlantingMergedEvent(mergeNo, {
mergeNo,
userId: userId.toString(),
accountSequence,
sourceOrderNos,
treeCount: 1,
provinceCode,
cityCode,
totalTreesMergedAfter,
}),
);
return merge;
}
/**
* 从持久化数据重建
*/
static reconstitute(data: PrePlantingMergeData): PrePlantingMerge {
const merge = new PrePlantingMerge(
data.mergeNo,
data.userId,
data.accountSequence,
data.sourceOrderNos,
data.provinceCode || null,
data.cityCode || null,
data.mergedAt,
);
merge._id = data.id || null;
merge._contractStatus = data.contractStatus;
merge._contractSignedAt = data.contractSignedAt || null;
merge._miningEnabledAt = data.miningEnabledAt || null;
return merge;
}
/**
* 签署合同
*/
signContract(): void {
if (this._contractStatus !== PrePlantingContractStatus.PENDING) {
throw new Error(`合并 ${this._mergeNo} 合同状态不允许签署: ${this._contractStatus}`);
}
this._contractStatus = PrePlantingContractStatus.SIGNED;
this._contractSignedAt = new Date();
this._miningEnabledAt = new Date();
this._domainEvents.push(
new PrePlantingContractSignedEvent(this._mergeNo, {
mergeNo: this._mergeNo,
userId: this._userId.toString(),
accountSequence: this._accountSequence,
provinceCode: this._provinceCode || '',
cityCode: this._cityCode || '',
treeCount: this._treeCount,
}),
);
}
setId(id: bigint): void {
this._id = id;
}
get id(): bigint | null { return this._id; }
get mergeNo(): string { return this._mergeNo; }
get userId(): bigint { return this._userId; }
get accountSequence(): string { return this._accountSequence; }
get sourceOrderNos(): string[] { return [...this._sourceOrderNos]; }
get treeCount(): number { return this._treeCount; }
get provinceCode(): string | null { return this._provinceCode; }
get cityCode(): string | null { return this._cityCode; }
get contractStatus(): PrePlantingContractStatus { return this._contractStatus; }
get contractSignedAt(): Date | null { return this._contractSignedAt; }
get miningEnabledAt(): Date | null { return this._miningEnabledAt; }
get mergedAt(): Date { return this._mergedAt; }
get domainEvents(): DomainEvent[] { return [...this._domainEvents]; }
clearDomainEvents(): void { this._domainEvents = []; }
toPersistence(): PrePlantingMergeData {
return {
id: this._id || undefined,
mergeNo: this._mergeNo,
userId: this._userId,
accountSequence: this._accountSequence,
sourceOrderNos: this._sourceOrderNos,
treeCount: this._treeCount,
provinceCode: this._provinceCode,
cityCode: this._cityCode,
contractStatus: this._contractStatus,
contractSignedAt: this._contractSignedAt,
miningEnabledAt: this._miningEnabledAt,
mergedAt: this._mergedAt,
};
}
}