@chevre/domain 25.0.0-alpha.1 → 25.0.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/chevre/repo/emailMessage.d.ts +5 -1
- package/lib/chevre/repo/transaction.d.ts +5 -1
- package/lib/chevre/repo/transaction.js +4 -0
- package/lib/chevre/service/transaction/placeOrder/confirm/potentialActions/sendEmailMessage.d.ts +0 -1
- package/lib/chevre/service/transaction/placeOrder/confirm/potentialActions/sendEmailMessage.js +2 -21
- package/lib/chevre/service/transaction/placeOrder/confirm/potentialActions.d.ts +0 -1
- package/lib/chevre/service/transaction/placeOrder/confirm/potentialActions.js +1 -6
- package/lib/chevre/service/transaction/placeOrder/confirm.d.ts +1 -3
- package/lib/chevre/service/transaction/placeOrder/confirm.js +17 -14
- package/lib/chevre/service/transaction/returnOrder/potentialActions/sendEmailMessage.d.ts +0 -1
- package/lib/chevre/service/transaction/returnOrder/potentialActions/sendEmailMessage.js +3 -18
- package/lib/chevre/service/transaction/returnOrder/potentialActions.d.ts +0 -1
- package/lib/chevre/service/transaction/returnOrder/potentialActions.js +0 -4
- package/lib/chevre/service/transaction/returnOrder.d.ts +0 -2
- package/lib/chevre/service/transaction/returnOrder.js +13 -12
- package/package.json +1 -1
|
@@ -15,7 +15,11 @@ export interface ISearchConditions {
|
|
|
15
15
|
};
|
|
16
16
|
about?: {
|
|
17
17
|
identifier?: {
|
|
18
|
-
|
|
18
|
+
/**
|
|
19
|
+
* 現時点でOnEventStatusChangedしかサポートしていない
|
|
20
|
+
* 2026-06-18
|
|
21
|
+
*/
|
|
22
|
+
$eq?: factory.creativeWork.message.email.AboutIdentifier.OnEventStatusChanged;
|
|
19
23
|
};
|
|
20
24
|
};
|
|
21
25
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Connection } from 'mongoose';
|
|
1
|
+
import type { Connection, UpdateQuery } from 'mongoose';
|
|
2
2
|
import { factory } from '../factory';
|
|
3
3
|
import { IDocType } from './mongoose/schemas/transaction';
|
|
4
4
|
interface IAggregationByStatus {
|
|
@@ -116,6 +116,10 @@ export declare class TransactionRepo {
|
|
|
116
116
|
filter: any;
|
|
117
117
|
$unset: any;
|
|
118
118
|
}): Promise<import("mongoose").UpdateWriteOpResult>;
|
|
119
|
+
updateById4migration(params: {
|
|
120
|
+
id: string;
|
|
121
|
+
update: UpdateQuery<IDocType>;
|
|
122
|
+
}): Promise<import("mongoose").UpdateWriteOpResult>;
|
|
119
123
|
/**
|
|
120
124
|
* 終了日時を一定期間過ぎたアクションを削除する
|
|
121
125
|
*/
|
|
@@ -297,6 +297,10 @@ class TransactionRepo {
|
|
|
297
297
|
return this.transactionModel.updateMany(params.filter, { $unset: params.$unset }, { timestamps: false })
|
|
298
298
|
.exec();
|
|
299
299
|
}
|
|
300
|
+
async updateById4migration(params) {
|
|
301
|
+
return this.transactionModel.updateOne({ _id: { $eq: params.id } }, params.update)
|
|
302
|
+
.exec();
|
|
303
|
+
}
|
|
300
304
|
/**
|
|
301
305
|
* 終了日時を一定期間過ぎたアクションを削除する
|
|
302
306
|
*/
|
package/lib/chevre/service/transaction/placeOrder/confirm/potentialActions/sendEmailMessage.d.ts
CHANGED
|
@@ -12,7 +12,6 @@ export declare function createSendEmailMessageActions(params: {
|
|
|
12
12
|
seller: factory.order.ISeller;
|
|
13
13
|
paymentMethods: factory.order.IReferencedInvoice[];
|
|
14
14
|
potentialActions?: factory.transaction.placeOrder.IPotentialActionsParams;
|
|
15
|
-
emailMessage?: factory.creativeWork.message.email.ICreativeWork;
|
|
16
15
|
}, setting: Pick<ISetting, 'defaultSenderEmail'>): Promise<{
|
|
17
16
|
emailMessages: factory.action.transfer.send.message.email.IObjectAsEmailMessage[];
|
|
18
17
|
sendEmailMessageActions: factory.transaction.placeOrder.IPotentialSendEmailMessageAction[];
|
package/lib/chevre/service/transaction/placeOrder/confirm/potentialActions/sendEmailMessage.js
CHANGED
|
@@ -3,20 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.createSendEmailMessageActions = createSendEmailMessageActions;
|
|
4
4
|
const emailMessageBuilder_1 = require("../../../../../emailMessageBuilder");
|
|
5
5
|
const factory_1 = require("../../../../../factory");
|
|
6
|
-
async function createSendEmailMessageActions(params,
|
|
7
|
-
// settings: Settings
|
|
8
|
-
setting) {
|
|
6
|
+
async function createSendEmailMessageActions(params, setting) {
|
|
9
7
|
// 注文配送メール送信設定
|
|
10
8
|
const emailMessages = [];
|
|
11
|
-
// const sendEmailMessageActions: factory.action.transfer.send.message.email.IAttributes[] = [];
|
|
12
9
|
const sendEmailMessageActions = [];
|
|
13
|
-
// const sendActionPurpose: factory.action.transfer.send.message.email.IPurpose = {
|
|
14
|
-
// typeOf: params.order.typeOf,
|
|
15
|
-
// orderNumber: params.order.orderNumber,
|
|
16
|
-
// price: params.order.price,
|
|
17
|
-
// priceCurrency: params.order.priceCurrency,
|
|
18
|
-
// orderDate: params.order.orderDate
|
|
19
|
-
// };
|
|
20
10
|
const sendEmailMessageOnOrderSentParams = params.potentialActions?.order?.potentialActions?.sendOrder?.potentialActions?.sendEmailMessage;
|
|
21
11
|
if (Array.isArray(sendEmailMessageOnOrderSentParams)) {
|
|
22
12
|
const orderAsCreateEmailParams = {
|
|
@@ -30,7 +20,7 @@ setting) {
|
|
|
30
20
|
order: orderAsCreateEmailParams,
|
|
31
21
|
index,
|
|
32
22
|
...(s.object !== undefined) ? { email: s.object } : undefined,
|
|
33
|
-
...(params.emailMessage !== undefined) ? { emailMessage: params.emailMessage } : undefined
|
|
23
|
+
// ...(params.emailMessage !== undefined) ? { emailMessage: params.emailMessage } : undefined
|
|
34
24
|
}, setting);
|
|
35
25
|
emailMessages.push(emailMessage);
|
|
36
26
|
// 送信アクション最適化に対応(2024-04-29~)
|
|
@@ -40,16 +30,7 @@ setting) {
|
|
|
40
30
|
};
|
|
41
31
|
// optimize(2024-05-07~)
|
|
42
32
|
sendEmailMessageActions.push({
|
|
43
|
-
// project: params.order.project,
|
|
44
|
-
// typeOf: factory.actionType.SendAction,
|
|
45
33
|
object: sendEmailMessageActionObject
|
|
46
|
-
// agent: params.order.project,
|
|
47
|
-
// recipient: {
|
|
48
|
-
// typeOf: params.order.customer.typeOf,
|
|
49
|
-
// id: params.order.customer.id
|
|
50
|
-
// },
|
|
51
|
-
// potentialActions: {},
|
|
52
|
-
// purpose: sendActionPurpose
|
|
53
34
|
});
|
|
54
35
|
}));
|
|
55
36
|
}
|
|
@@ -15,7 +15,6 @@ export declare function createPotentialActions(params: {
|
|
|
15
15
|
seller: factory.order.ISeller;
|
|
16
16
|
paymentMethods: factory.order.IReferencedInvoice[];
|
|
17
17
|
potentialActions?: factory.transaction.placeOrder.IPotentialActionsParams;
|
|
18
|
-
emailMessage?: factory.creativeWork.message.email.ICreativeWork;
|
|
19
18
|
}, setting: Pick<ISetting, 'defaultSenderEmail'>): Promise<{
|
|
20
19
|
potentialActions: factory.transaction.placeOrder.IPotentialActions;
|
|
21
20
|
emailMessages: factory.creativeWork.message.email.ICreativeWork[];
|
|
@@ -5,14 +5,9 @@ const sendEmailMessage_1 = require("./potentialActions/sendEmailMessage");
|
|
|
5
5
|
/**
|
|
6
6
|
* 取引のポストアクションを作成する
|
|
7
7
|
*/
|
|
8
|
-
async function createPotentialActions(params,
|
|
9
|
-
// settings: Settings
|
|
10
|
-
setting) {
|
|
8
|
+
async function createPotentialActions(params, setting) {
|
|
11
9
|
// 注文処理開始メール送信設定
|
|
12
10
|
const { emailMessages, sendEmailMessageActions } = await (0, sendEmailMessage_1.createSendEmailMessageActions)(params, setting);
|
|
13
|
-
// const sendOrderActionAttributes: factory.transaction.placeOrder.IPotentialSendOrderAction = {
|
|
14
|
-
// potentialActions: { sendEmailMessage: sendEmailMessageActions }
|
|
15
|
-
// };
|
|
16
11
|
return {
|
|
17
12
|
emailMessages,
|
|
18
13
|
potentialActions: {
|
|
@@ -4,7 +4,6 @@ import type { AuthorizeOfferActionRepo } from '../../../repo/action/authorizeOff
|
|
|
4
4
|
import type { AssetTransactionRepo } from '../../../repo/assetTransaction';
|
|
5
5
|
import type { AuthorizationRepo } from '../../../repo/authorization';
|
|
6
6
|
import type { ConfirmationNumberRepo } from '../../../repo/confirmationNumber';
|
|
7
|
-
import type { EmailMessageRepo } from '../../../repo/emailMessage';
|
|
8
7
|
import type { MessageRepo } from '../../../repo/message';
|
|
9
8
|
import type { OrderInTransactionRepo } from '../../../repo/orderInTransaction';
|
|
10
9
|
import type { ProjectRepo } from '../../../repo/project';
|
|
@@ -18,7 +17,6 @@ interface IConfirmOperationRepos {
|
|
|
18
17
|
authorizeOfferAction: AuthorizeOfferActionRepo;
|
|
19
18
|
assetTransaction: AssetTransactionRepo;
|
|
20
19
|
authorization: AuthorizationRepo;
|
|
21
|
-
emailMessage?: EmailMessageRepo;
|
|
22
20
|
message: MessageRepo;
|
|
23
21
|
project: ProjectRepo;
|
|
24
22
|
placeOrder: PlaceOrderRepo;
|
|
@@ -41,7 +39,7 @@ interface IConfirmOptions {
|
|
|
41
39
|
*/
|
|
42
40
|
maxNumCreditCardPaymentMethod: number;
|
|
43
41
|
/**
|
|
44
|
-
* 取引ドキュメントのresult.orderを保管しないオプション(2026-06-15~)
|
|
42
|
+
* 取引ドキュメントのresult.order,result,numAcceptedOffersを保管しないオプション(2026-06-15~)
|
|
45
43
|
*/
|
|
46
44
|
disableResultOrder: boolean;
|
|
47
45
|
}
|
|
@@ -136,17 +136,18 @@ function confirm(params, options) {
|
|
|
136
136
|
acceptedOffers, payTransactions, customer,
|
|
137
137
|
...(typeof code === 'string') ? { code } : undefined
|
|
138
138
|
}, options);
|
|
139
|
-
//
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
139
|
+
// discontinue emailMessageRepo
|
|
140
|
+
// // デフォルトEメールメッセージを検索
|
|
141
|
+
// let emailMessageOnOrderSent: factory.creativeWork.message.email.ICreativeWork | undefined;
|
|
142
|
+
// if (repos.emailMessage !== undefined) {
|
|
143
|
+
// const searchEmailMessagesResult = await repos.emailMessage.search({
|
|
144
|
+
// limit: 1,
|
|
145
|
+
// page: 1,
|
|
146
|
+
// project: { id: { $eq: transaction.project.id } },
|
|
147
|
+
// about: { identifier: { $eq: factory.creativeWork.message.email.AboutIdentifier.OnOrderSent } }
|
|
148
|
+
// });
|
|
149
|
+
// emailMessageOnOrderSent = searchEmailMessagesResult.shift();
|
|
150
|
+
// }
|
|
150
151
|
// ポストアクションを作成
|
|
151
152
|
const setting = await repos.setting.findOne({ project: { id: { $eq: '*' } } }, ['defaultSenderEmail']);
|
|
152
153
|
if (typeof setting?.defaultSenderEmail !== 'string') {
|
|
@@ -160,7 +161,7 @@ function confirm(params, options) {
|
|
|
160
161
|
// order: orderWithAcceptedOffers, // 現時点でcreateEmailMessageでorder.acceptedOffersを使用している(2024-02-06~)
|
|
161
162
|
// transaction: transaction,
|
|
162
163
|
...(params.potentialActions !== undefined) ? { potentialActions: params.potentialActions } : undefined,
|
|
163
|
-
...(emailMessageOnOrderSent !== undefined) ? { emailMessage: emailMessageOnOrderSent } : undefined
|
|
164
|
+
// ...(emailMessageOnOrderSent !== undefined) ? { emailMessage: emailMessageOnOrderSent } : undefined
|
|
164
165
|
},
|
|
165
166
|
// settings
|
|
166
167
|
setting);
|
|
@@ -372,9 +373,11 @@ function createResult(params, options) {
|
|
|
372
373
|
placingOrder,
|
|
373
374
|
result: {
|
|
374
375
|
authorizeActions, // 追加(2024-01-17~)
|
|
375
|
-
numAcceptedOffers: params.acceptedOffers.length, // 追加(2024-01-17~)
|
|
376
376
|
...(typeof params.code === 'string') ? { code: params.code } : undefined,
|
|
377
|
-
...((!options.disableResultOrder) && { order: orderAsResult }) // support disableResultOrder(2026-06-15~)
|
|
377
|
+
...((!options.disableResultOrder) && { order: orderAsResult }), // support disableResultOrder(2026-06-15~)
|
|
378
|
+
...((!options.disableResultOrder) && {
|
|
379
|
+
numAcceptedOffers: params.acceptedOffers.length, // 追加(2024-01-17~)
|
|
380
|
+
}) // support disableResultOrder(2026-06-17~)
|
|
378
381
|
},
|
|
379
382
|
...(typeof eventId === 'string') ? { eventId } : undefined,
|
|
380
383
|
...(Array.isArray(reservationIds)) ? { reservationIds } : undefined
|
|
@@ -4,7 +4,6 @@ type IPotentialSendEmailMessageAction = factory.action.transfer.returnAction.ord
|
|
|
4
4
|
export declare function createSendEmailMessaegActionsOnReturn(params: {
|
|
5
5
|
order: Pick<factory.order.IOrder, 'confirmationNumber' | 'customer' | 'orderDate' | 'orderNumber' | 'orderStatus' | 'orderedItem' | 'paymentMethods' | 'price' | 'priceCurrency' | 'seller' | 'typeOf'>;
|
|
6
6
|
returnOrderActionParams?: factory.transaction.returnOrder.IReturnOrderActionParams;
|
|
7
|
-
emailMessageOnOrderReturned?: factory.creativeWork.message.email.ICreativeWork;
|
|
8
7
|
}, setting: Pick<ISetting, 'defaultSenderEmail'>): Promise<{
|
|
9
8
|
emailMessagesOnReturn: factory.action.transfer.send.message.email.IObjectAsEmailMessage[];
|
|
10
9
|
sendEmailMessaegActionsOnReturn: IPotentialSendEmailMessageAction[];
|
|
@@ -7,13 +7,6 @@ async function createSendEmailMessaegActionsOnReturn(params,
|
|
|
7
7
|
// settings: Settings
|
|
8
8
|
setting) {
|
|
9
9
|
const order = params.order;
|
|
10
|
-
// const sendActionPurpose: factory.action.transfer.send.message.email.IPurpose = {
|
|
11
|
-
// typeOf: order.typeOf,
|
|
12
|
-
// orderNumber: order.orderNumber,
|
|
13
|
-
// price: order.price,
|
|
14
|
-
// priceCurrency: order.priceCurrency,
|
|
15
|
-
// orderDate: order.orderDate
|
|
16
|
-
// };
|
|
17
10
|
// 返品後のEメール送信アクション
|
|
18
11
|
const emailMessagesOnReturn = [];
|
|
19
12
|
const sendEmailMessaegActionsOnReturn = [];
|
|
@@ -24,24 +17,16 @@ setting) {
|
|
|
24
17
|
order,
|
|
25
18
|
index,
|
|
26
19
|
...(sendEmailMessageParams.object !== undefined) ? { email: sendEmailMessageParams.object } : undefined,
|
|
27
|
-
...(params.emailMessageOnOrderReturned !== undefined)
|
|
28
|
-
|
|
29
|
-
|
|
20
|
+
// ...(params.emailMessageOnOrderReturned !== undefined)
|
|
21
|
+
// ? { emailMessage: params.emailMessageOnOrderReturned }
|
|
22
|
+
// : undefined
|
|
30
23
|
}, setting);
|
|
31
24
|
emailMessagesOnReturn.push(emailMessage);
|
|
32
25
|
return {
|
|
33
|
-
// project: order.project, // optimize(2024-06-25~)
|
|
34
|
-
// typeOf: factory.actionType.SendAction, // optimize(2024-06-25~)
|
|
35
|
-
// standardize object(2024-06-27~)
|
|
36
|
-
// object: emailMessage
|
|
37
26
|
object: {
|
|
38
27
|
identifier: emailMessage.identifier,
|
|
39
28
|
typeOf: factory_1.factory.creativeWorkType.EmailMessage
|
|
40
29
|
}
|
|
41
|
-
// agent: order.project, // optimize(2024-06-25~)
|
|
42
|
-
// recipient: { typeOf: order.customer.typeOf, id: order.customer.id }, // optimize(2024-06-25~)
|
|
43
|
-
// potentialActions: {} // optimize(2024-06-25~)
|
|
44
|
-
// purpose: sendActionPurpose // optimize(2024-06-25~)
|
|
45
30
|
};
|
|
46
31
|
})));
|
|
47
32
|
}
|
|
@@ -6,7 +6,6 @@ declare function createPotentialActions(params: {
|
|
|
6
6
|
orders: IReturningOrder4potentialActions[];
|
|
7
7
|
potentialActions?: factory.transaction.returnOrder.IPotentialActionsParams;
|
|
8
8
|
transaction: Pick<factory.transaction.returnOrder.ITransaction, 'agent' | 'object'>;
|
|
9
|
-
emailMessageOnOrderReturned?: factory.creativeWork.message.email.ICreativeWork;
|
|
10
9
|
}, setting: Pick<ISetting, 'defaultSenderEmail'>): Promise<{
|
|
11
10
|
emailMessages: factory.action.transfer.send.message.email.IObjectAsEmailMessage[];
|
|
12
11
|
potentialActions: factory.transaction.returnOrder.IPotentialActions;
|
|
@@ -22,9 +22,6 @@ setting) {
|
|
|
22
22
|
...(returnOrderActionParams !== undefined) ? { returnOrderActionParams } : undefined
|
|
23
23
|
}, setting);
|
|
24
24
|
emailMessages.push(...emailMessagesOnReturnInvoice);
|
|
25
|
-
// discontinue(2026-04-18~)
|
|
26
|
-
// // ポイント特典の数だけ、返却アクションを作成
|
|
27
|
-
// const returnPointAwardActions = await createReturnPointAwardActions({ ...params, order });
|
|
28
25
|
// 返品後のEメール送信アクション
|
|
29
26
|
const { emailMessagesOnReturn, sendEmailMessaegActionsOnReturn } = await (0, sendEmailMessage_1.createSendEmailMessaegActionsOnReturn)({
|
|
30
27
|
...params,
|
|
@@ -34,7 +31,6 @@ setting) {
|
|
|
34
31
|
emailMessages.push(...emailMessagesOnReturn);
|
|
35
32
|
const potentialActionsOnReturnOrder = {
|
|
36
33
|
returnPaymentMethod: returnPaymentMethodActions,
|
|
37
|
-
// returnPointAward: returnPointAwardActions, // discontinue(2026-04-18~)
|
|
38
34
|
sendEmailMessage: sendEmailMessaegActionsOnReturn
|
|
39
35
|
};
|
|
40
36
|
const returnOrderObject = {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { factory } from '../../factory';
|
|
2
2
|
import type { AcceptedOfferRepo } from '../../repo/acceptedOffer';
|
|
3
|
-
import type { EmailMessageRepo } from '../../repo/emailMessage';
|
|
4
3
|
import type { EventRepo } from '../../repo/event';
|
|
5
4
|
import type { MerchantReturnPolicyRepo } from '../../repo/merchantReturnPolicy';
|
|
6
5
|
import type { MessageRepo } from '../../repo/message';
|
|
@@ -41,7 +40,6 @@ type ITaskAndTransactionOperation<T> = (repos: IExportTasksByIdRepos) => Promise
|
|
|
41
40
|
declare function start(params: factory.transaction.returnOrder.IStartParamsWithoutDetail): IStartOperation<IStartedTransaction>;
|
|
42
41
|
interface IConfirmRepos {
|
|
43
42
|
acceptedOffer: AcceptedOfferRepo;
|
|
44
|
-
emailMessage?: EmailMessageRepo;
|
|
45
43
|
message: MessageRepo;
|
|
46
44
|
order: OrderRepo;
|
|
47
45
|
setting: SettingRepo;
|
|
@@ -112,17 +112,18 @@ function confirm(params) {
|
|
|
112
112
|
'orderedItem', 'paymentMethods', 'price', 'priceCurrency', 'project', 'seller', 'typeOf'
|
|
113
113
|
]
|
|
114
114
|
});
|
|
115
|
-
//
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
115
|
+
// discontinue emailMessageRepo
|
|
116
|
+
// // デフォルトEメールメッセージを検索
|
|
117
|
+
// let emailMessageOnOrderReturned: factory.creativeWork.message.email.ICreativeWork | undefined;
|
|
118
|
+
// if (repos.emailMessage !== undefined) {
|
|
119
|
+
// const searchEmailMessagesResult = await repos.emailMessage.search({
|
|
120
|
+
// limit: 1,
|
|
121
|
+
// page: 1,
|
|
122
|
+
// project: { id: { $eq: transaction.project.id } },
|
|
123
|
+
// about: { identifier: { $eq: factory.creativeWork.message.email.AboutIdentifier.OnOrderReturned } }
|
|
124
|
+
// });
|
|
125
|
+
// emailMessageOnOrderReturned = searchEmailMessagesResult.shift();
|
|
126
|
+
// }
|
|
126
127
|
const setting = await repos.setting.findOne({ project: { id: { $eq: '*' } } }, ['defaultSenderEmail']);
|
|
127
128
|
if (typeof setting?.defaultSenderEmail !== 'string') {
|
|
128
129
|
throw new factory_1.factory.errors.NotFound('setting.defaultSenderEmail');
|
|
@@ -133,7 +134,7 @@ function confirm(params) {
|
|
|
133
134
|
orders: returningOrders,
|
|
134
135
|
transaction: transaction,
|
|
135
136
|
...(params.potentialActions !== undefined) ? { potentialActions: params.potentialActions } : undefined,
|
|
136
|
-
...(emailMessageOnOrderReturned !== undefined) ? { emailMessageOnOrderReturned } : undefined
|
|
137
|
+
// ...(emailMessageOnOrderReturned !== undefined) ? { emailMessageOnOrderReturned } : undefined
|
|
137
138
|
},
|
|
138
139
|
// settings
|
|
139
140
|
setting);
|
package/package.json
CHANGED