feat: ✨ add order-cancelled avatax adapter
This commit is contained in:
parent
0013af2f6d
commit
d458452573
10 changed files with 82 additions and 15 deletions
|
@ -1,9 +1,6 @@
|
|||
fragment OrderCancelledSubscription on Order {
|
||||
id
|
||||
privateMetadata {
|
||||
key
|
||||
value
|
||||
}
|
||||
externalId: metafield(key: "externalId")
|
||||
channel {
|
||||
id
|
||||
slug
|
||||
|
|
|
@ -53,6 +53,11 @@ export type ValidateAddressArgs = {
|
|||
address: AvataxAddress;
|
||||
};
|
||||
|
||||
export type VoidTransactionArgs = {
|
||||
transactionCode: string;
|
||||
companyCode: string;
|
||||
};
|
||||
|
||||
export class AvataxClient {
|
||||
private client: Avatax;
|
||||
private logger: Logger;
|
||||
|
@ -73,6 +78,16 @@ export class AvataxClient {
|
|||
return this.client.commitTransaction(args);
|
||||
}
|
||||
|
||||
async voidTransaction({
|
||||
transactionCode,
|
||||
companyCode,
|
||||
}: {
|
||||
transactionCode: string;
|
||||
companyCode: string;
|
||||
}) {
|
||||
return this.client.voidTransaction({ transactionCode, companyCode });
|
||||
}
|
||||
|
||||
async validateAddress({ address }: ValidateAddressArgs) {
|
||||
return this.client.resolveAddress(address);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@ import { AvataxConfig, defaultAvataxConfig } from "./avatax-connection-schema";
|
|||
import { AvataxCalculateTaxesAdapter } from "./calculate-taxes/avatax-calculate-taxes-adapter";
|
||||
import { AvataxOrderCreatedAdapter } from "./order-created/avatax-order-created-adapter";
|
||||
import { AvataxOrderFulfilledAdapter } from "./order-fulfilled/avatax-order-fulfilled-adapter";
|
||||
import { AvataxOrderCancelledAdapter } from "./order-cancelled/avatax-order-cancelled-adapter";
|
||||
import { OrderCancelledPayload } from "../../pages/api/webhooks/order-cancelled";
|
||||
|
||||
export class AvataxWebhookService implements ProviderWebhookService {
|
||||
config = defaultAvataxConfig;
|
||||
|
@ -52,9 +54,10 @@ export class AvataxWebhookService implements ProviderWebhookService {
|
|||
return response;
|
||||
}
|
||||
|
||||
async cancelOrder(payload: OrderCancelledEventSubscriptionFragment) {
|
||||
// todo: implement
|
||||
async cancelOrder(payload: OrderCancelledPayload) {
|
||||
this.logger.debug("cancelOrder", payload);
|
||||
return { ok: true };
|
||||
const adapter = new AvataxOrderCancelledAdapter(this.config);
|
||||
|
||||
await adapter.send(payload);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
import { Logger, createLogger } from "../../../lib/logger";
|
||||
import { OrderCancelledPayload } from "../../../pages/api/webhooks/order-cancelled";
|
||||
import { WebhookAdapter } from "../../taxes/tax-webhook-adapter";
|
||||
import { AvataxClient, VoidTransactionArgs } from "../avatax-client";
|
||||
import { AvataxConfig } from "../avatax-connection-schema";
|
||||
import { AvataxOrderCancelledPayloadTransformer } from "./avatax-order-cancelled-payload-transformer";
|
||||
|
||||
export type AvataxOrderCancelledTarget = VoidTransactionArgs;
|
||||
|
||||
export class AvataxOrderCancelledAdapter implements WebhookAdapter<OrderCancelledPayload, void> {
|
||||
private logger: Logger;
|
||||
|
||||
constructor(private readonly config: AvataxConfig) {
|
||||
this.logger = createLogger({ name: "AvataxOrderCancelledAdapter" });
|
||||
}
|
||||
|
||||
async send(payload: OrderCancelledPayload) {
|
||||
this.logger.debug("Transforming the Saleor payload for cancelling transaction with Avatax...");
|
||||
|
||||
const payloadTransformer = new AvataxOrderCancelledPayloadTransformer(this.config);
|
||||
const target = payloadTransformer.transform({ ...payload });
|
||||
|
||||
this.logger.debug("Calling Avatax commitTransaction with transformed payload...");
|
||||
|
||||
const client = new AvataxClient(this.config);
|
||||
|
||||
await client.voidTransaction(target);
|
||||
|
||||
this.logger.debug("Avatax commitTransaction succesfully responded");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
import { OrderCancelledPayload } from "../../../pages/api/webhooks/order-cancelled";
|
||||
import { taxProviderUtils } from "../../taxes/tax-provider-utils";
|
||||
import { AvataxConfig } from "../avatax-connection-schema";
|
||||
import { AvataxOrderCancelledTarget } from "./avatax-order-cancelled-adapter";
|
||||
|
||||
export class AvataxOrderCancelledPayloadTransformer {
|
||||
constructor(private readonly config: AvataxConfig) {}
|
||||
|
||||
transform({ order }: OrderCancelledPayload): AvataxOrderCancelledTarget {
|
||||
if (!order) {
|
||||
throw new Error("Order is required");
|
||||
}
|
||||
|
||||
const transactionCode = taxProviderUtils.resolveOptionalOrThrow(order.externalId);
|
||||
|
||||
return {
|
||||
transactionCode,
|
||||
companyCode: this.config.companyCode ?? "",
|
||||
};
|
||||
}
|
||||
}
|
|
@ -13,6 +13,7 @@ import { AvataxWebhookService } from "../avatax/avatax-webhook.service";
|
|||
import { ProviderConnection } from "../provider-connections/provider-connections";
|
||||
import { TaxJarWebhookService } from "../taxjar/taxjar-webhook.service";
|
||||
import { ProviderWebhookService } from "./tax-provider-webhook";
|
||||
import { OrderCancelledPayload } from "../../pages/api/webhooks/order-cancelled";
|
||||
|
||||
// todo: refactor to a factory
|
||||
class ActiveTaxProviderService implements ProviderWebhookService {
|
||||
|
@ -57,8 +58,8 @@ class ActiveTaxProviderService implements ProviderWebhookService {
|
|||
return this.client.fulfillOrder(payload);
|
||||
}
|
||||
|
||||
async cancelOrder(payload: OrderCancelledEventSubscriptionFragment) {
|
||||
return this.client.cancelOrder(payload);
|
||||
async cancelOrder(payload: OrderCancelledPayload) {
|
||||
this.client.cancelOrder(payload);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
* If it ever happens, we have nothing to fall back to, so we throw an error.
|
||||
* Should only be used for values that are required for further calculation.
|
||||
*/
|
||||
function resolveOptionalOrThrow<T>(value: T | undefined, error?: Error): T {
|
||||
if (value === undefined) {
|
||||
function resolveOptionalOrThrow<T>(value: T | undefined | null, error?: Error): T {
|
||||
if (value === undefined || value === null) {
|
||||
throw error
|
||||
? error
|
||||
: new Error("Could not resolve data. Value needed for further calculation is undefined.");
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { SyncWebhookResponsesMap } from "@saleor/app-sdk/handlers/next";
|
||||
import {
|
||||
OrderCancelledEventSubscriptionFragment,
|
||||
OrderCreatedSubscriptionFragment,
|
||||
OrderFulfilledSubscriptionFragment,
|
||||
TaxBaseFragment,
|
||||
} from "../../../generated/graphql";
|
||||
import { OrderCancelledPayload } from "../../pages/api/webhooks/order-cancelled";
|
||||
|
||||
export type CalculateTaxesResponse = SyncWebhookResponsesMap["ORDER_CALCULATE_TAXES"];
|
||||
|
||||
|
@ -14,5 +14,5 @@ export interface ProviderWebhookService {
|
|||
calculateTaxes: (payload: TaxBaseFragment) => Promise<CalculateTaxesResponse>;
|
||||
createOrder: (payload: OrderCreatedSubscriptionFragment) => Promise<CreateOrderResponse>;
|
||||
fulfillOrder: (payload: OrderFulfilledSubscriptionFragment) => Promise<{ ok: boolean }>;
|
||||
cancelOrder: (payload: OrderCancelledEventSubscriptionFragment) => Promise<any>;
|
||||
cancelOrder: (payload: OrderCancelledPayload) => Promise<void>;
|
||||
}
|
||||
|
|
|
@ -50,6 +50,5 @@ export class TaxJarWebhookService implements ProviderWebhookService {
|
|||
async cancelOrder(payload: OrderCancelledEventSubscriptionFragment) {
|
||||
// todo: implement
|
||||
this.logger.debug("cancelOrder", payload);
|
||||
return { ok: true };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ export const config = {
|
|||
},
|
||||
};
|
||||
|
||||
type OrderCancelledPayload = Extract<
|
||||
export type OrderCancelledPayload = Extract<
|
||||
OrderCancelledEventSubscriptionFragment,
|
||||
{ __typename: "OrderCancelled" }
|
||||
>;
|
||||
|
|
Loading…
Reference in a new issue