Merged PR 378: API実装(ライセンス発行キャンセルAPI)
## 概要 [Task2498: API実装(ライセンス発行キャンセルAPI)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2498) - 元PBI or タスクへのリンク(内容・目的などはそちらにあるはず) - 何をどう変更したか、追加したライブラリなど ライセンス発行をキャンセルするAPIを実装 下位のアカウント情報と、上位のアカウント情報をセットすると、パートナー関係であるかを返す関数を追加 既存のユニットテストのライセンス作成箇所で、注文ID、削除日時、削除注文IDを指定できるように修正 - このPull Requestでの対象/対象外 - 影響範囲(他の機能にも影響があるか) 既存ユニットテストのライセンス作成部分 ## レビューポイント - 特にレビューしてほしい箇所 パートナー関係かどうかを返す箇所、共通的に使いやすいかどうか 14日より経過していた場合の箇所、ライセンスの有効期限の定数を使っているが分けたほうが良いか ## UIの変更 - Before/Afterのスクショなど - スクショ置き場 ## 動作確認状況 - ローカルで確認 ■正常系 ライセンス発行のキャンセルが完了できる(第一階層で実行) ライセンス発行のキャンセルが完了できる(第二階層で実行) キャンセルした発行の注文状態が発行待ちに戻る 発行されたライセンスは物理削除される 論理削除されていたライセンスは未割当で、削除前の状態に戻る ■異常系 第一、第二階層以外で実行した場合はエラー キャンセル対象の発行が存在しない場合エラー キャンセル対象の発行が14日より経過していた場合はエラー キャンセル対象の発行のライセンスが使われていた場合はエラー 自身のパートナー以外の発行をキャンセルしようとした場合、エラー ## 補足 - 相談、参考資料などがあれば
This commit is contained in:
parent
2d378b8e66
commit
7524abbae6
@ -48,6 +48,9 @@ export const ErrorCodes = [
|
||||
'E010806', // ライセンス割り当て不可エラー
|
||||
'E010807', // ライセンス割り当て解除済みエラー
|
||||
'E010808', // ライセンス注文キャンセル不可エラー
|
||||
'E010809', // ライセンス発行キャンセル不可エラー(ステータスが変えられている場合)
|
||||
'E010810', // ライセンス発行キャンセル不可エラー(発行から一定期間経過した場合)
|
||||
'E010811', // ライセンス発行キャンセル不可エラー(発行したライセンスが割り当てされている場合)
|
||||
'E010908', // タイピストグループ不在エラー
|
||||
'E011001', // ワークタイプ重複エラー
|
||||
'E011002', // ワークタイプ登録上限超過エラー
|
||||
|
||||
@ -37,6 +37,9 @@ export const errors: Errors = {
|
||||
E010806: 'License is unavailable Error',
|
||||
E010807: 'License is already deallocated Error',
|
||||
E010808: 'Order cancel failed Error',
|
||||
E010809: 'Already license order status changed Error',
|
||||
E010810: 'Cancellation period expired error',
|
||||
E010811: 'Already license allocated Error',
|
||||
E010908: 'Typist Group not exist Error',
|
||||
E011001: 'Thiw WorkTypeID already used Error',
|
||||
E011002: 'WorkTypeID create limit exceeded Error',
|
||||
|
||||
@ -636,12 +636,12 @@ export class AccountsController {
|
||||
|
||||
const context = makeContext(payload.userId);
|
||||
|
||||
// TODO: 発行キャンセル処理(仮)。API実装のタスク(2498)で本実装
|
||||
// await this.accountService.cancelIssue(
|
||||
// context,
|
||||
// body.poNumber,
|
||||
// body.orderedAccountId,
|
||||
// );
|
||||
await this.accountService.cancelIssue(
|
||||
context,
|
||||
payload.userId,
|
||||
body.poNumber,
|
||||
body.orderedAccountId,
|
||||
);
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
@ -32,10 +32,14 @@ import {
|
||||
getUserFromExternalId,
|
||||
getUsers,
|
||||
makeTestUser,
|
||||
makeHierarchicalAccounts,
|
||||
} from '../../common/test/utility';
|
||||
import { AccountsService } from './accounts.service';
|
||||
import { Context, makeContext } from '../../common/log';
|
||||
import {
|
||||
LICENSE_ALLOCATED_STATUS,
|
||||
LICENSE_ISSUE_STATUS,
|
||||
LICENSE_TYPE,
|
||||
OPTION_ITEM_VALUE_TYPE,
|
||||
TIERS,
|
||||
USER_ROLES,
|
||||
@ -51,8 +55,12 @@ import {
|
||||
import { AdB2cService } from '../../gateways/adb2c/adb2c.service';
|
||||
import { BlobstorageService } from '../../gateways/blobstorage/blobstorage.service';
|
||||
import { UserGroupsRepositoryService } from '../../repositories/user_groups/user_groups.repository.service';
|
||||
import {
|
||||
createOrder,
|
||||
selectLicense,
|
||||
selectOrderLicense,
|
||||
} from '../licenses/test/utility';
|
||||
import { WorktypesRepositoryService } from '../../repositories/worktypes/worktypes.repository.service';
|
||||
import exp from 'constants';
|
||||
|
||||
describe('createAccount', () => {
|
||||
let source: DataSource = null;
|
||||
@ -1827,14 +1835,79 @@ describe('getPartnerAccount', () => {
|
||||
).account;
|
||||
|
||||
// 所有ライセンスを追加(親:3、子1:1、子2:2)
|
||||
await createLicense(source, parentAccountId);
|
||||
await createLicense(source, parentAccountId);
|
||||
await createLicense(source, parentAccountId);
|
||||
await createLicense(
|
||||
source,
|
||||
1,
|
||||
null,
|
||||
parentAccountId,
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
1,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
await createLicense(
|
||||
source,
|
||||
2,
|
||||
null,
|
||||
parentAccountId,
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
1,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
await createLicense(
|
||||
source,
|
||||
3,
|
||||
null,
|
||||
parentAccountId,
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
1,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
await createLicense(
|
||||
source,
|
||||
4,
|
||||
null,
|
||||
childAccountId1,
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
2,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
|
||||
await createLicense(source, childAccountId1);
|
||||
|
||||
await createLicense(source, childAccountId2);
|
||||
await createLicense(source, childAccountId2);
|
||||
await createLicense(
|
||||
source,
|
||||
5,
|
||||
null,
|
||||
childAccountId2,
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
3,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
await createLicense(
|
||||
source,
|
||||
6,
|
||||
null,
|
||||
childAccountId2,
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
3,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
|
||||
// ライセンス注文を追加(子1→親:10ライセンス、子2→親:5ライセンス)
|
||||
await createLicenseOrder(
|
||||
@ -1980,7 +2053,12 @@ describe('getPartnerAccount', () => {
|
||||
}
|
||||
|
||||
// 有効期限未設定のライセンスを1件追加(子1)
|
||||
await createLicense(source, childAccountId1);
|
||||
await createLicenseSetExpiryDateAndStatus(
|
||||
source,
|
||||
childAccountId1,
|
||||
null,
|
||||
'Unallocated',
|
||||
);
|
||||
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
const accountId = parentAccountId;
|
||||
@ -2172,9 +2250,42 @@ describe('issueLicense', () => {
|
||||
});
|
||||
|
||||
// 親のライセンスを作成する(3個)
|
||||
await createLicense(source, parentAccountId);
|
||||
await createLicense(source, parentAccountId);
|
||||
await createLicense(source, parentAccountId);
|
||||
await createLicense(
|
||||
source,
|
||||
1,
|
||||
null,
|
||||
parentAccountId,
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
1,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
await createLicense(
|
||||
source,
|
||||
2,
|
||||
null,
|
||||
parentAccountId,
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
1,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
await createLicense(
|
||||
source,
|
||||
3,
|
||||
null,
|
||||
parentAccountId,
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
1,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
// 子から親への注文を作成する(2個)
|
||||
await createLicenseOrder(
|
||||
source,
|
||||
@ -2231,9 +2342,42 @@ describe('issueLicense', () => {
|
||||
role: 'admin',
|
||||
});
|
||||
// 親のライセンスを作成する(3個)
|
||||
await createLicense(source, parentAccountId);
|
||||
await createLicense(source, parentAccountId);
|
||||
await createLicense(source, parentAccountId);
|
||||
await createLicense(
|
||||
source,
|
||||
1,
|
||||
null,
|
||||
parentAccountId,
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
1,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
await createLicense(
|
||||
source,
|
||||
2,
|
||||
null,
|
||||
parentAccountId,
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
1,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
await createLicense(
|
||||
source,
|
||||
3,
|
||||
null,
|
||||
parentAccountId,
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
1,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
// 子から親への注文を作成する(2個)
|
||||
await createLicenseOrder(
|
||||
source,
|
||||
@ -2289,9 +2433,42 @@ describe('issueLicense', () => {
|
||||
});
|
||||
|
||||
// 親のライセンスを作成する(3個)
|
||||
await createLicense(source, parentAccountId);
|
||||
await createLicense(source, parentAccountId);
|
||||
await createLicense(source, parentAccountId);
|
||||
await createLicense(
|
||||
source,
|
||||
1,
|
||||
null,
|
||||
parentAccountId,
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
1,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
await createLicense(
|
||||
source,
|
||||
2,
|
||||
null,
|
||||
parentAccountId,
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
1,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
await createLicense(
|
||||
source,
|
||||
3,
|
||||
null,
|
||||
parentAccountId,
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
1,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
// 子から親への注文を作成する(4個)
|
||||
await createLicenseOrder(
|
||||
source,
|
||||
@ -3414,3 +3591,297 @@ describe('createWorktype', () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
describe('ライセンス発行キャンセル', () => {
|
||||
let source: DataSource = null;
|
||||
beforeEach(async () => {
|
||||
source = new DataSource({
|
||||
type: 'sqlite',
|
||||
database: ':memory:',
|
||||
logging: false,
|
||||
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
|
||||
synchronize: true, // trueにすると自動的にmigrationが行われるため注意
|
||||
});
|
||||
return source.initialize();
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await source.destroy();
|
||||
source = null;
|
||||
});
|
||||
it('ライセンス発行のキャンセルが完了する(第一階層で実行)', async () => {
|
||||
const module = await makeTestingModule(source);
|
||||
const { tier1Accounts: tier1Accounts, tier4Accounts: tier4Accounts } =
|
||||
await makeHierarchicalAccounts(source);
|
||||
const tier5Accounts = await makeTestAccount(source, {
|
||||
parent_account_id: tier4Accounts[0].account.id,
|
||||
tier: 5,
|
||||
});
|
||||
const poNumber = 'CANCEL_TEST';
|
||||
const date = new Date();
|
||||
date.setDate(date.getDate() - 10);
|
||||
await createOrder(
|
||||
source,
|
||||
poNumber,
|
||||
tier5Accounts.account.id,
|
||||
tier5Accounts.account.parent_account_id,
|
||||
date,
|
||||
1,
|
||||
LICENSE_ISSUE_STATUS.ISSUED,
|
||||
);
|
||||
date.setDate(date.getDate() + 10);
|
||||
// 発行時に論理削除されたライセンス情報
|
||||
await createLicense(
|
||||
source,
|
||||
1,
|
||||
date,
|
||||
tier5Accounts.account.id,
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
null,
|
||||
date,
|
||||
1,
|
||||
);
|
||||
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
await service.cancelIssue(
|
||||
makeContext('trackingId'),
|
||||
tier1Accounts[0].users[0].external_id,
|
||||
poNumber,
|
||||
tier5Accounts.account.id,
|
||||
);
|
||||
|
||||
// 発行待ちに戻した注文の状態確認
|
||||
const orderRecord = await selectOrderLicense(
|
||||
source,
|
||||
tier5Accounts.account.id,
|
||||
poNumber,
|
||||
);
|
||||
expect(orderRecord.orderLicense.issued_at).toBe(null);
|
||||
expect(orderRecord.orderLicense.status).toBe(
|
||||
LICENSE_ISSUE_STATUS.ISSUE_REQUESTING,
|
||||
);
|
||||
// 未割当に戻したライセンスの状態確認
|
||||
const licenseRecord = await selectLicense(source, 1);
|
||||
expect(licenseRecord.license.status).toBe(
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
);
|
||||
expect(licenseRecord.license.delete_order_id).toBe(null);
|
||||
expect(licenseRecord.license.deleted_at).toBe(null);
|
||||
});
|
||||
it('ライセンス発行のキャンセルが完了する(第二階層で実行)', async () => {
|
||||
const module = await makeTestingModule(source);
|
||||
const { tier2Accounts: tier2Accounts, tier4Accounts: tier4Accounts } =
|
||||
await makeHierarchicalAccounts(source);
|
||||
const tier5Accounts = await makeTestAccount(source, {
|
||||
parent_account_id: tier4Accounts[0].account.id,
|
||||
tier: 5,
|
||||
});
|
||||
const poNumber = 'CANCEL_TEST';
|
||||
const date = new Date();
|
||||
date.setDate(date.getDate() - 10);
|
||||
await createOrder(
|
||||
source,
|
||||
poNumber,
|
||||
tier5Accounts.account.id,
|
||||
tier5Accounts.account.parent_account_id,
|
||||
date,
|
||||
1,
|
||||
LICENSE_ISSUE_STATUS.ISSUED,
|
||||
);
|
||||
date.setDate(date.getDate() + 10);
|
||||
// 発行時に論理削除されたライセンス情報
|
||||
await createLicense(
|
||||
source,
|
||||
1,
|
||||
date,
|
||||
tier5Accounts.account.id,
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
null,
|
||||
date,
|
||||
1,
|
||||
);
|
||||
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
await service.cancelIssue(
|
||||
makeContext('trackingId'),
|
||||
tier2Accounts[0].users[0].external_id,
|
||||
poNumber,
|
||||
tier5Accounts.account.id,
|
||||
);
|
||||
|
||||
// 発行待ちに戻した注文の状態確認
|
||||
const orderRecord = await selectOrderLicense(
|
||||
source,
|
||||
tier5Accounts.account.id,
|
||||
poNumber,
|
||||
);
|
||||
expect(orderRecord.orderLicense.issued_at).toBe(null);
|
||||
expect(orderRecord.orderLicense.status).toBe(
|
||||
LICENSE_ISSUE_STATUS.ISSUE_REQUESTING,
|
||||
);
|
||||
// 未割当に戻したライセンスの状態確認
|
||||
const licenseRecord = await selectLicense(source, 1);
|
||||
expect(licenseRecord.license.status).toBe(
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
);
|
||||
expect(licenseRecord.license.delete_order_id).toBe(null);
|
||||
expect(licenseRecord.license.deleted_at).toBe(null);
|
||||
});
|
||||
it('キャンセル対象の発行が存在しない場合エラー', async () => {
|
||||
const module = await makeTestingModule(source);
|
||||
const { tier1Accounts: tier1Accounts, tier4Accounts: tier4Accounts } =
|
||||
await makeHierarchicalAccounts(source);
|
||||
const tier5Accounts = await makeTestAccount(source, {
|
||||
parent_account_id: tier4Accounts[0].account.id,
|
||||
tier: 5,
|
||||
});
|
||||
const poNumber = 'CANCEL_TEST';
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
await expect(
|
||||
service.cancelIssue(
|
||||
makeContext('trackingId'),
|
||||
tier1Accounts[0].users[0].external_id,
|
||||
poNumber,
|
||||
tier5Accounts.account.id,
|
||||
),
|
||||
).rejects.toEqual(
|
||||
new HttpException(makeErrorResponse('E010809'), HttpStatus.BAD_REQUEST),
|
||||
);
|
||||
});
|
||||
it('キャンセル対象の発行が14日より経過していた場合エラー', async () => {
|
||||
const module = await makeTestingModule(source);
|
||||
const { tier1Accounts: tier1Accounts, tier4Accounts: tier4Accounts } =
|
||||
await makeHierarchicalAccounts(source);
|
||||
const tier5Accounts = await makeTestAccount(source, {
|
||||
parent_account_id: tier4Accounts[0].account.id,
|
||||
tier: 5,
|
||||
});
|
||||
const poNumber = 'CANCEL_TEST';
|
||||
const date = new Date();
|
||||
date.setDate(date.getDate() - 15);
|
||||
await createOrder(
|
||||
source,
|
||||
poNumber,
|
||||
tier5Accounts.account.id,
|
||||
tier5Accounts.account.parent_account_id,
|
||||
date,
|
||||
1,
|
||||
LICENSE_ISSUE_STATUS.ISSUED,
|
||||
);
|
||||
await createLicense(
|
||||
source,
|
||||
1,
|
||||
date,
|
||||
tier5Accounts.account.id,
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
1,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
await expect(
|
||||
service.cancelIssue(
|
||||
makeContext('trackingId'),
|
||||
tier1Accounts[0].users[0].external_id,
|
||||
poNumber,
|
||||
tier5Accounts.account.id,
|
||||
),
|
||||
).rejects.toEqual(
|
||||
new HttpException(makeErrorResponse('E010810'), HttpStatus.BAD_REQUEST),
|
||||
);
|
||||
});
|
||||
it('キャンセル対象の発行のライセンスが使われていた場合エラー', async () => {
|
||||
const module = await makeTestingModule(source);
|
||||
const { tier1Accounts: tier1Accounts, tier4Accounts: tier4Accounts } =
|
||||
await makeHierarchicalAccounts(source);
|
||||
const tier5Accounts = await makeTestAccount(source, {
|
||||
parent_account_id: tier4Accounts[0].account.id,
|
||||
tier: 5,
|
||||
});
|
||||
const poNumber = 'CANCEL_TEST';
|
||||
const date = new Date();
|
||||
date.setDate(date.getDate() - 14);
|
||||
await createOrder(
|
||||
source,
|
||||
poNumber,
|
||||
tier5Accounts.account.id,
|
||||
tier5Accounts.account.parent_account_id,
|
||||
date,
|
||||
1,
|
||||
LICENSE_ISSUE_STATUS.ISSUED,
|
||||
);
|
||||
await createLicense(
|
||||
source,
|
||||
1,
|
||||
date,
|
||||
tier5Accounts.account.id,
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.ALLOCATED,
|
||||
null,
|
||||
1,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
await expect(
|
||||
service.cancelIssue(
|
||||
makeContext('trackingId'),
|
||||
tier1Accounts[0].users[0].external_id,
|
||||
poNumber,
|
||||
tier5Accounts.account.id,
|
||||
),
|
||||
).rejects.toEqual(
|
||||
new HttpException(makeErrorResponse('E010811'), HttpStatus.BAD_REQUEST),
|
||||
);
|
||||
});
|
||||
it('自身のパートナー以外の発行をキャンセルしようとした場合、エラー', async () => {
|
||||
const module = await makeTestingModule(source);
|
||||
const { tier1Accounts: tier1Accounts } = await makeHierarchicalAccounts(
|
||||
source,
|
||||
);
|
||||
const tier5Accounts = await makeTestAccount(source, {
|
||||
parent_account_id: 100,
|
||||
tier: 5,
|
||||
});
|
||||
const poNumber = 'CANCEL_TEST';
|
||||
const date = new Date();
|
||||
date.setDate(date.getDate() - 14);
|
||||
await createOrder(
|
||||
source,
|
||||
poNumber,
|
||||
tier5Accounts.account.id,
|
||||
tier5Accounts.account.parent_account_id,
|
||||
date,
|
||||
1,
|
||||
LICENSE_ISSUE_STATUS.ISSUED,
|
||||
);
|
||||
await createLicense(
|
||||
source,
|
||||
1,
|
||||
date,
|
||||
tier5Accounts.account.id,
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
1,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
await expect(
|
||||
service.cancelIssue(
|
||||
makeContext('trackingId'),
|
||||
tier1Accounts[0].users[0].external_id,
|
||||
poNumber,
|
||||
tier5Accounts.account.id,
|
||||
),
|
||||
).rejects.toEqual(
|
||||
new HttpException(makeErrorResponse('E000108'), HttpStatus.UNAUTHORIZED),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@ -40,6 +40,9 @@ import {
|
||||
LicensesShortageError,
|
||||
AlreadyIssuedError,
|
||||
OrderNotFoundError,
|
||||
AlreadyLicenseStatusChangedError,
|
||||
AlreadyLicenseAllocatedError,
|
||||
CancellationPeriodExpiredError,
|
||||
} from '../../repositories/licenses/errors/types';
|
||||
import { BlobstorageService } from '../../gateways/blobstorage/blobstorage.service';
|
||||
import {
|
||||
@ -1057,6 +1060,90 @@ export class AccountsService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ライセンス発行をキャンセルする
|
||||
* @param context
|
||||
* @param extarnalId
|
||||
* @param poNumber
|
||||
* @param orderedAccountId
|
||||
*/
|
||||
async cancelIssue(
|
||||
context: Context,
|
||||
extarnalId: string,
|
||||
poNumber: string,
|
||||
orderedAccountId: number,
|
||||
): Promise<void> {
|
||||
this.logger.log(
|
||||
`[IN] [${context.trackingId}] ${this.cancelIssue.name} | params: { ` +
|
||||
`extarnalId: ${extarnalId}, ` +
|
||||
`poNumber: ${poNumber}, ` +
|
||||
`orderedAccountId: ${orderedAccountId}, };`,
|
||||
);
|
||||
let myAccountId: number;
|
||||
|
||||
try {
|
||||
// ユーザIDからアカウントIDを取得する
|
||||
myAccountId = (
|
||||
await this.usersRepository.findUserByExternalId(extarnalId)
|
||||
).account_id;
|
||||
} catch (e) {
|
||||
this.logger.error(`error=${e}`);
|
||||
switch (e.constructor) {
|
||||
default:
|
||||
throw new HttpException(
|
||||
makeErrorResponse('E009999'),
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
this.logger.log(`[OUT] [${context.trackingId}] ${this.cancelIssue.name}`);
|
||||
}
|
||||
|
||||
// 注文元アカウントIDの親世代を取得
|
||||
const parentAccountIds = await this.accountRepository.getHierarchyParents(
|
||||
orderedAccountId,
|
||||
);
|
||||
// 自身が存在しない場合、エラー
|
||||
if (!parentAccountIds.includes(myAccountId)) {
|
||||
this.logger.log(`[OUT] [${context.trackingId}] ${this.cancelIssue.name}`);
|
||||
throw new HttpException(
|
||||
makeErrorResponse('E000108'),
|
||||
HttpStatus.UNAUTHORIZED,
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
// 発行キャンセル処理
|
||||
await this.accountRepository.cancelIssue(orderedAccountId, poNumber);
|
||||
} catch (e) {
|
||||
this.logger.error(`error=${e}`);
|
||||
switch (e.constructor) {
|
||||
case AlreadyLicenseStatusChangedError:
|
||||
throw new HttpException(
|
||||
makeErrorResponse('E010809'),
|
||||
HttpStatus.BAD_REQUEST,
|
||||
);
|
||||
case CancellationPeriodExpiredError:
|
||||
throw new HttpException(
|
||||
makeErrorResponse('E010810'),
|
||||
HttpStatus.BAD_REQUEST,
|
||||
);
|
||||
case AlreadyLicenseAllocatedError:
|
||||
throw new HttpException(
|
||||
makeErrorResponse('E010811'),
|
||||
HttpStatus.BAD_REQUEST,
|
||||
);
|
||||
default:
|
||||
throw new HttpException(
|
||||
makeErrorResponse('E009999'),
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
this.logger.log(`[OUT] [${context.trackingId}] ${this.cancelIssue.name}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ワークタイプ一覧を取得します
|
||||
* @param context
|
||||
|
||||
@ -20,17 +20,26 @@ export const getSortCriteria = async (dataSource: DataSource) => {
|
||||
|
||||
export const createLicense = async (
|
||||
datasource: DataSource,
|
||||
licenseId: number,
|
||||
expiry_date: Date,
|
||||
accountId: number,
|
||||
type: string,
|
||||
status: string,
|
||||
allocated_user_id: number,
|
||||
order_id: number,
|
||||
deleted_at: Date,
|
||||
delete_order_id: number,
|
||||
): Promise<void> => {
|
||||
const { identifiers } = await datasource.getRepository(License).insert({
|
||||
expiry_date: null,
|
||||
id: licenseId,
|
||||
expiry_date: expiry_date,
|
||||
account_id: accountId,
|
||||
type: 'NORMAL',
|
||||
status: 'Unallocated',
|
||||
allocated_user_id: null,
|
||||
order_id: null,
|
||||
deleted_at: null,
|
||||
delete_order_id: null,
|
||||
type: type,
|
||||
status: status,
|
||||
allocated_user_id: allocated_user_id,
|
||||
order_id: order_id,
|
||||
deleted_at: deleted_at,
|
||||
delete_order_id: delete_order_id,
|
||||
created_by: 'test_runner',
|
||||
created_at: new Date(),
|
||||
updated_by: 'updater',
|
||||
|
||||
@ -346,6 +346,9 @@ describe('DBテスト', () => {
|
||||
LICENSE_TYPE.CARD,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
await createCardLicense(source, license_id, issueId, cardLicenseKey);
|
||||
await createCardLicenseIssue(source, issueId);
|
||||
@ -386,6 +389,9 @@ describe('DBテスト', () => {
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
// 2件目、expiry_dateがnull(OneYear)
|
||||
await createLicense(
|
||||
@ -396,6 +402,9 @@ describe('DBテスト', () => {
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
// 3件目、1件目と同じ有効期限
|
||||
await createLicense(
|
||||
@ -406,6 +415,9 @@ describe('DBテスト', () => {
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
// 4件目、expiry_dateが一番遠いデータ
|
||||
await createLicense(
|
||||
@ -416,6 +428,9 @@ describe('DBテスト', () => {
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
// 5件目、expiry_dateがnull(OneYear)
|
||||
await createLicense(
|
||||
@ -426,6 +441,9 @@ describe('DBテスト', () => {
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
// 6件目、ライセンス状態が割当済
|
||||
await createLicense(
|
||||
@ -436,6 +454,9 @@ describe('DBテスト', () => {
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.ALLOCATED,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
// 7件目、ライセンス状態が削除済
|
||||
await createLicense(
|
||||
@ -446,6 +467,9 @@ describe('DBテスト', () => {
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.DELETED,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
// 8件目、別アカウントの未割当のライセンス
|
||||
await createLicense(
|
||||
@ -456,6 +480,9 @@ describe('DBテスト', () => {
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
// 9件目、有効期限切れのライセンス
|
||||
await createLicense(
|
||||
@ -466,6 +493,9 @@ describe('DBテスト', () => {
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
const service = module.get<LicensesService>(LicensesService);
|
||||
const context = makeContext('userId');
|
||||
@ -518,6 +548,9 @@ describe('ライセンス割り当て', () => {
|
||||
LICENSE_TYPE.CARD,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
await createLicenseAllocationHistory(source, 1, userId, 1, 'NONE');
|
||||
|
||||
@ -570,6 +603,9 @@ describe('ライセンス割り当て', () => {
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.REUSABLE,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
await createLicenseAllocationHistory(source, 1, userId, 1, 'NONE');
|
||||
|
||||
@ -616,6 +652,9 @@ describe('ライセンス割り当て', () => {
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.ALLOCATED,
|
||||
userId,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
await createLicense(
|
||||
source,
|
||||
@ -625,6 +664,9 @@ describe('ライセンス割り当て', () => {
|
||||
LICENSE_TYPE.CARD,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
await createLicenseAllocationHistory(source, 1, userId, 1, 'NONE');
|
||||
|
||||
@ -697,6 +739,9 @@ describe('ライセンス割り当て', () => {
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.ALLOCATED,
|
||||
userId,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
await createLicense(
|
||||
source,
|
||||
@ -706,6 +751,9 @@ describe('ライセンス割り当て', () => {
|
||||
LICENSE_TYPE.CARD,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
await createLicenseAllocationHistory(source, 1, userId, 1, 'NONE');
|
||||
|
||||
@ -742,6 +790,9 @@ describe('ライセンス割り当て', () => {
|
||||
LICENSE_TYPE.CARD,
|
||||
LICENSE_ALLOCATED_STATUS.ALLOCATED,
|
||||
userId,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
await createLicense(
|
||||
source,
|
||||
@ -751,6 +802,9 @@ describe('ライセンス割り当て', () => {
|
||||
LICENSE_TYPE.CARD,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
await createLicenseAllocationHistory(source, 1, userId, 1, 'CARD');
|
||||
|
||||
@ -787,6 +841,9 @@ describe('ライセンス割り当て', () => {
|
||||
LICENSE_TYPE.TRIAL,
|
||||
LICENSE_ALLOCATED_STATUS.ALLOCATED,
|
||||
userId,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
await createLicense(
|
||||
source,
|
||||
@ -796,6 +853,9 @@ describe('ライセンス割り当て', () => {
|
||||
LICENSE_TYPE.CARD,
|
||||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
await createLicenseAllocationHistory(source, 1, userId, 1, 'TRIAL');
|
||||
|
||||
@ -832,6 +892,9 @@ describe('ライセンス割り当て', () => {
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.REUSABLE,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
|
||||
const service = module.get<UsersService>(UsersService);
|
||||
@ -863,6 +926,9 @@ describe('ライセンス割り当て', () => {
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.ALLOCATED,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
await createLicense(
|
||||
source,
|
||||
@ -872,6 +938,9 @@ describe('ライセンス割り当て', () => {
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.DELETED,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
|
||||
const service = module.get<UsersService>(UsersService);
|
||||
@ -927,6 +996,9 @@ describe('ライセンス割り当て解除', () => {
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.ALLOCATED,
|
||||
userId,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
await createLicenseAllocationHistory(source, 1, userId, 1, 'NONE');
|
||||
|
||||
@ -987,6 +1059,9 @@ describe('ライセンス割り当て解除', () => {
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.ALLOCATED,
|
||||
2,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
await createLicense(
|
||||
source,
|
||||
@ -996,6 +1071,9 @@ describe('ライセンス割り当て解除', () => {
|
||||
LICENSE_TYPE.NORMAL,
|
||||
LICENSE_ALLOCATED_STATUS.REUSABLE,
|
||||
userId,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
await createLicenseAllocationHistory(source, 1, userId, 1, 'NONE');
|
||||
|
||||
@ -1037,6 +1115,7 @@ describe('ライセンス注文キャンセル', () => {
|
||||
poNumber,
|
||||
tier2Accounts[0].account.id,
|
||||
tier2Accounts[0].account.parent_account_id,
|
||||
null,
|
||||
10,
|
||||
'Issue Requesting',
|
||||
);
|
||||
@ -1046,6 +1125,7 @@ describe('ライセンス注文キャンセル', () => {
|
||||
poNumber,
|
||||
tier2Accounts[0].account.id,
|
||||
tier2Accounts[0].account.parent_account_id,
|
||||
null,
|
||||
10,
|
||||
'Order Canceled',
|
||||
);
|
||||
@ -1078,6 +1158,7 @@ describe('ライセンス注文キャンセル', () => {
|
||||
poNumber,
|
||||
tier2Accounts[0].account.id,
|
||||
tier2Accounts[0].account.parent_account_id,
|
||||
null,
|
||||
10,
|
||||
'Issued',
|
||||
);
|
||||
@ -1106,6 +1187,7 @@ describe('ライセンス注文キャンセル', () => {
|
||||
poNumber,
|
||||
tier2Accounts[0].account.id,
|
||||
tier2Accounts[0].account.parent_account_id,
|
||||
null,
|
||||
10,
|
||||
'Order Canceled',
|
||||
);
|
||||
|
||||
@ -15,6 +15,9 @@ export const createLicense = async (
|
||||
type: string,
|
||||
status: string,
|
||||
allocated_user_id: number,
|
||||
order_id: number,
|
||||
deleted_at: Date,
|
||||
delete_order_id: number,
|
||||
): Promise<void> => {
|
||||
const { identifiers } = await datasource.getRepository(License).insert({
|
||||
id: licenseId,
|
||||
@ -23,9 +26,9 @@ export const createLicense = async (
|
||||
type: type,
|
||||
status: status,
|
||||
allocated_user_id: allocated_user_id,
|
||||
order_id: null,
|
||||
deleted_at: null,
|
||||
delete_order_id: null,
|
||||
order_id: order_id,
|
||||
deleted_at: deleted_at,
|
||||
delete_order_id: delete_order_id,
|
||||
created_by: 'test_runner',
|
||||
created_at: new Date(),
|
||||
updated_by: 'updater',
|
||||
@ -100,6 +103,7 @@ export const createOrder = async (
|
||||
poNumber: string,
|
||||
fromId: number,
|
||||
toId: number,
|
||||
issuedAt: Date,
|
||||
quantity: number,
|
||||
status: string,
|
||||
): Promise<void> => {
|
||||
@ -108,7 +112,7 @@ export const createOrder = async (
|
||||
from_account_id: fromId,
|
||||
to_account_id: toId,
|
||||
ordered_at: new Date(),
|
||||
issued_at: null,
|
||||
issued_at: issuedAt,
|
||||
quantity: quantity,
|
||||
status: status,
|
||||
canceled_at: null,
|
||||
|
||||
@ -20,6 +20,7 @@ import {
|
||||
} from '../../common/types/sort/util';
|
||||
import {
|
||||
LICENSE_ALLOCATED_STATUS,
|
||||
LICENSE_EXPIRATION_THRESHOLD_DAYS,
|
||||
LICENSE_ISSUE_STATUS,
|
||||
TIERS,
|
||||
} from '../../constants';
|
||||
@ -28,6 +29,12 @@ import {
|
||||
PartnerLicenseInfoForRepository,
|
||||
} from '../../features/accounts/types/types';
|
||||
import { AccountNotFoundError } from './errors/types';
|
||||
import {
|
||||
AlreadyLicenseAllocatedError,
|
||||
AlreadyLicenseStatusChangedError,
|
||||
CancellationPeriodExpiredError,
|
||||
} from '../licenses/errors/types';
|
||||
import { DateWithZeroTime } from '../../features/licenses/types/types';
|
||||
|
||||
@Injectable()
|
||||
export class AccountsRepositoryService {
|
||||
@ -572,4 +579,110 @@ export class AccountsRepositoryService {
|
||||
|
||||
return accounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* 対象のアカウントIDの親世代のアカウントIDをすべて取得する
|
||||
* 順番は、階層(tier)の下位から上位に向かって格納
|
||||
* @param targetAccountId
|
||||
* @returns accountIds
|
||||
*/
|
||||
async getHierarchyParents(targetAccountId: number): Promise<number[]> {
|
||||
return await this.dataSource.transaction(async (entityManager) => {
|
||||
const accountRepository = entityManager.getRepository(Account);
|
||||
const maxTierDifference = TIERS.TIER5 - TIERS.TIER1;
|
||||
const parentAccountIds = [];
|
||||
|
||||
let currentAccountId = targetAccountId;
|
||||
// システム的な最大の階層差異分、親を参照する
|
||||
for (let i = 0; i < maxTierDifference; i++) {
|
||||
const account = await accountRepository.findOne({
|
||||
where: {
|
||||
id: currentAccountId,
|
||||
},
|
||||
});
|
||||
if (!account) {
|
||||
break;
|
||||
}
|
||||
|
||||
parentAccountIds.push(account.parent_account_id);
|
||||
currentAccountId = account.parent_account_id;
|
||||
}
|
||||
|
||||
return parentAccountIds;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 注文元アカウントIDとPOナンバーに紐づくライセンス発行をキャンセルする
|
||||
* @param orderedAccountId:キャンセルしたい発行の注文元アカウントID
|
||||
* @param poNumber:POナンバー
|
||||
*/
|
||||
async cancelIssue(orderedAccountId: number, poNumber: string): Promise<void> {
|
||||
await this.dataSource.transaction(async (entityManager) => {
|
||||
const orderRepo = entityManager.getRepository(LicenseOrder);
|
||||
|
||||
// キャンセル対象の発行を取得
|
||||
const targetOrder = await orderRepo.findOne({
|
||||
where: {
|
||||
from_account_id: orderedAccountId,
|
||||
po_number: poNumber,
|
||||
status: LICENSE_ISSUE_STATUS.ISSUED,
|
||||
},
|
||||
});
|
||||
|
||||
// キャンセル対象の発行が存在しない場合エラー
|
||||
if (!targetOrder) {
|
||||
throw new AlreadyLicenseStatusChangedError(
|
||||
`Cancel issue is failed. Already license order status changed. fromAccountId: ${orderedAccountId}, poNumber: ${poNumber}`,
|
||||
);
|
||||
}
|
||||
|
||||
// キャンセル可能な日付(発行日から14日経過)かどうかに判定する時刻を取得する
|
||||
const currentDateWithoutTime = new DateWithZeroTime();
|
||||
const issuedDateWithoutTime = new DateWithZeroTime(targetOrder.issued_at);
|
||||
const timeDifference =
|
||||
currentDateWithoutTime.getTime() - issuedDateWithoutTime.getTime();
|
||||
const daysDifference = Math.floor(timeDifference / (1000 * 60 * 60 * 24));
|
||||
// 発行日から14日経過しているかをチェック
|
||||
if (daysDifference > LICENSE_EXPIRATION_THRESHOLD_DAYS) {
|
||||
throw new CancellationPeriodExpiredError(
|
||||
`Cancel issue is failed. Cancellation period expired. fromAccountId: ${orderedAccountId}, poNumber: ${poNumber}`,
|
||||
);
|
||||
}
|
||||
// すでに割り当て済みライセンスを含む注文か確認する
|
||||
const licenseRepo = entityManager.getRepository(License);
|
||||
const allocatedLicense = await licenseRepo.findOne({
|
||||
where: {
|
||||
order_id: targetOrder.id,
|
||||
status: Not(LICENSE_ALLOCATED_STATUS.UNALLOCATED),
|
||||
},
|
||||
});
|
||||
|
||||
// 存在した場合エラー
|
||||
if (allocatedLicense) {
|
||||
throw new AlreadyLicenseAllocatedError(
|
||||
`Cancel issue is failed. Already license allocated. fromAccountId: ${orderedAccountId}, poNumber: ${poNumber}`,
|
||||
);
|
||||
}
|
||||
|
||||
// 更新用の変数に値をコピー
|
||||
const updatedOrder = { ...targetOrder };
|
||||
|
||||
// 注文を発行待ちに戻す
|
||||
updatedOrder.issued_at = null;
|
||||
updatedOrder.status = LICENSE_ISSUE_STATUS.ISSUE_REQUESTING;
|
||||
await orderRepo.save(updatedOrder);
|
||||
// 発行時に削除したライセンスを未割当に戻す
|
||||
await licenseRepo.update(
|
||||
{ delete_order_id: targetOrder.id },
|
||||
{
|
||||
status: LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||||
deleted_at: null,
|
||||
delete_order_id: null,
|
||||
},
|
||||
);
|
||||
// 発行時に発行されたライセンスを削除する
|
||||
await licenseRepo.delete({ order_id: targetOrder.id });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,3 +24,12 @@ export class LicenseAlreadyDeallocatedError extends Error {}
|
||||
|
||||
// 注文キャンセル失敗エラー
|
||||
export class CancelOrderFailedError extends Error {}
|
||||
|
||||
// ライセンス発行キャンセル不可エラー(ステータスが変えられている場合)
|
||||
export class AlreadyLicenseStatusChangedError extends Error {}
|
||||
|
||||
// ライセンス発行キャンセル不可エラー(発行から一定期間経過した場合)
|
||||
export class CancellationPeriodExpiredError extends Error {}
|
||||
|
||||
// ライセンス発行キャンセル不可エラー(発行したライセンスが割り当てされている場合)
|
||||
export class AlreadyLicenseAllocatedError extends Error {}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { DataSource, In, IsNull, MoreThanOrEqual } from 'typeorm';
|
||||
import { DataSource, In } from 'typeorm';
|
||||
import {
|
||||
LicenseOrder,
|
||||
License,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user