fix(c3): 扑空转 not_met 前 requireOrder 校验(44003)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
5bfd0f4748
commit
2e4c916949
@ -1,6 +1,7 @@
|
|||||||
import { describe, expect, it, vi } from 'vitest';
|
import { describe, expect, it, vi } from 'vitest';
|
||||||
import { AbnormalService } from './abnormal.service.js';
|
import { AbnormalService } from './abnormal.service.js';
|
||||||
import type { PrismaService } from '../prisma/prisma.service.js';
|
import type { PrismaService } from '../prisma/prisma.service.js';
|
||||||
|
import { ErrorCodes } from '../common/error-codes.js';
|
||||||
import { runWithRequestContext } from '../common/context/request-context.js';
|
import { runWithRequestContext } from '../common/context/request-context.js';
|
||||||
import type { RequestContext } from '../common/context/request-context.js';
|
import type { RequestContext } from '../common/context/request-context.js';
|
||||||
|
|
||||||
@ -20,12 +21,14 @@ function makeService(
|
|||||||
recordAbnormalFindMany?: ReturnType<typeof vi.fn>;
|
recordAbnormalFindMany?: ReturnType<typeof vi.fn>;
|
||||||
recordAbnormalCount?: ReturnType<typeof vi.fn>;
|
recordAbnormalCount?: ReturnType<typeof vi.fn>;
|
||||||
orderUpdate?: ReturnType<typeof vi.fn>;
|
orderUpdate?: ReturnType<typeof vi.fn>;
|
||||||
|
orderFindUnique?: ReturnType<typeof vi.fn>;
|
||||||
} = {},
|
} = {},
|
||||||
) {
|
) {
|
||||||
const recordAbnormalCreate = overrides.recordAbnormalCreate ?? vi.fn().mockResolvedValue({ id: 'a1' });
|
const recordAbnormalCreate = overrides.recordAbnormalCreate ?? vi.fn().mockResolvedValue({ id: 'a1' });
|
||||||
const recordAbnormalFindMany = overrides.recordAbnormalFindMany ?? vi.fn().mockResolvedValue([]);
|
const recordAbnormalFindMany = overrides.recordAbnormalFindMany ?? vi.fn().mockResolvedValue([]);
|
||||||
const recordAbnormalCount = overrides.recordAbnormalCount ?? vi.fn().mockResolvedValue(0);
|
const recordAbnormalCount = overrides.recordAbnormalCount ?? vi.fn().mockResolvedValue(0);
|
||||||
const orderUpdate = overrides.orderUpdate ?? vi.fn().mockResolvedValue({ id: 'o1', orderStatus: 'not_met' });
|
const orderUpdate = overrides.orderUpdate ?? vi.fn().mockResolvedValue({ id: 'o1', orderStatus: 'not_met' });
|
||||||
|
const orderFindUnique = overrides.orderFindUnique ?? vi.fn().mockResolvedValue({ id: 'o1', orderStatus: 'assigned' });
|
||||||
|
|
||||||
const prisma = {
|
const prisma = {
|
||||||
client: {
|
client: {
|
||||||
@ -34,11 +37,11 @@ function makeService(
|
|||||||
findMany: recordAbnormalFindMany,
|
findMany: recordAbnormalFindMany,
|
||||||
count: recordAbnormalCount,
|
count: recordAbnormalCount,
|
||||||
},
|
},
|
||||||
order: { update: orderUpdate },
|
order: { update: orderUpdate, findUnique: orderFindUnique },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const service = new AbnormalService(prisma as unknown as PrismaService);
|
const service = new AbnormalService(prisma as unknown as PrismaService);
|
||||||
return { service, recordAbnormalCreate, recordAbnormalFindMany, recordAbnormalCount, orderUpdate };
|
return { service, recordAbnormalCreate, recordAbnormalFindMany, recordAbnormalCount, orderUpdate, orderFindUnique };
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('AbnormalService', () => {
|
describe('AbnormalService', () => {
|
||||||
@ -149,6 +152,29 @@ describe('AbnormalService', () => {
|
|||||||
expect(recordAbnormalCreate).not.toHaveBeenCalled();
|
expect(recordAbnormalCreate).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('report 扑空 order 不存在 → ORDER_NOT_FOUND(44003),不写工单/异常', async () => {
|
||||||
|
const orderFindUnique = vi.fn().mockResolvedValue(null);
|
||||||
|
const { service, recordAbnormalCreate, orderUpdate } = makeService({ orderFindUnique });
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
runWithRequestContext(ctx, () =>
|
||||||
|
service.report({
|
||||||
|
abnormalType: 'not_met',
|
||||||
|
elderId: 'e1',
|
||||||
|
orderId: 'o-missing',
|
||||||
|
abnormalDesc: '老人不在家',
|
||||||
|
visitTime: '2026-10-15T09:30:00',
|
||||||
|
visitLat: 25.01,
|
||||||
|
visitLng: 102.7,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
).rejects.toMatchObject({ response: { code: ErrorCodes.ORDER_NOT_FOUND } });
|
||||||
|
|
||||||
|
expect(orderFindUnique).toHaveBeenCalledWith({ where: { id: 'o-missing' } });
|
||||||
|
expect(orderUpdate).not.toHaveBeenCalled();
|
||||||
|
expect(recordAbnormalCreate).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
it('list 按 abnormal_type/notify_status/handle_status/老人 筛选', async () => {
|
it('list 按 abnormal_type/notify_status/handle_status/老人 筛选', async () => {
|
||||||
const recordAbnormalFindMany = vi.fn().mockResolvedValue([{ id: 'a1' }]);
|
const recordAbnormalFindMany = vi.fn().mockResolvedValue([{ id: 'a1' }]);
|
||||||
const recordAbnormalCount = vi.fn().mockResolvedValue(1);
|
const recordAbnormalCount = vi.fn().mockResolvedValue(1);
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
import { BadRequestException, Injectable } from '@nestjs/common';
|
import { BadRequestException, HttpStatus, Injectable } from '@nestjs/common';
|
||||||
import { PrismaService } from '../prisma/prisma.service.js';
|
import { PrismaService } from '../prisma/prisma.service.js';
|
||||||
import { getRequestContext } from '../common/context/request-context.js';
|
import { getRequestContext } from '../common/context/request-context.js';
|
||||||
|
import { BusinessException } from '../common/business-exception.js';
|
||||||
|
import { ErrorCodes } from '../common/error-codes.js';
|
||||||
import { ListAbnormalQuery, NOT_MET, ReportAbnormalDto } from './dto.js';
|
import { ListAbnormalQuery, NOT_MET, ReportAbnormalDto } from './dto.js';
|
||||||
|
|
||||||
/** ISO datetime 字符串 → Date。业务时区为北京时间(UTC+8),与 order.service 口径一致。 */
|
/** ISO datetime 字符串 → Date。业务时区为北京时间(UTC+8),与 order.service 口径一致。 */
|
||||||
@ -35,7 +37,8 @@ export class AbnormalService {
|
|||||||
|
|
||||||
if (dto.abnormalType === NOT_MET) {
|
if (dto.abnormalType === NOT_MET) {
|
||||||
this.assertNotMetEvidence(dto);
|
this.assertNotMetEvidence(dto);
|
||||||
// 扑空:工单转 not_met(原因 + 到访时间)。
|
// 扑空:工单须存在,再转 not_met(原因 + 到访时间)。
|
||||||
|
await this.requireOrder(dto.orderId!);
|
||||||
await this.prisma.client.order.update({
|
await this.prisma.client.order.update({
|
||||||
where: { id: dto.orderId! },
|
where: { id: dto.orderId! },
|
||||||
data: {
|
data: {
|
||||||
@ -93,4 +96,13 @@ export class AbnormalService {
|
|||||||
throw new BadRequestException('扑空须填写到访时间、定位、原因与关联工单(3003)');
|
throw new BadRequestException('扑空须填写到访时间、定位、原因与关联工单(3003)');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 工单须存在(扑空转 not_met 前校验,44003),循 order.service 的 requireOrder。 */
|
||||||
|
private async requireOrder(id: string): Promise<Record<string, unknown>> {
|
||||||
|
const order = await this.prisma.client.order.findUnique({ where: { id } });
|
||||||
|
if (!order) {
|
||||||
|
throw new BusinessException(ErrorCodes.ORDER_NOT_FOUND, '工单不存在', HttpStatus.NOT_FOUND);
|
||||||
|
}
|
||||||
|
return order;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user