2020-12-01 13:13:05 +00:00
|
|
|
import { IMoney, subtractMoney } from "@saleor/components/Money";
|
|
|
|
import { FormsetData } from "@saleor/hooks/useFormset";
|
|
|
|
|
2021-01-20 16:16:43 +00:00
|
|
|
import {
|
|
|
|
LineItemData,
|
|
|
|
OrderReturnFormData
|
|
|
|
} from "../components/OrderReturnPage/form";
|
|
|
|
import {
|
|
|
|
getAllOrderFulfilledLines,
|
|
|
|
getById
|
|
|
|
} from "../components/OrderReturnPage/utils";
|
|
|
|
import {
|
|
|
|
OrderDetails_order,
|
|
|
|
OrderDetails_order_fulfillments_lines,
|
|
|
|
OrderDetails_order_lines
|
|
|
|
} from "../types/OrderDetails";
|
2020-12-01 13:13:05 +00:00
|
|
|
import {
|
|
|
|
OrderRefundData_order,
|
|
|
|
OrderRefundData_order_fulfillments,
|
|
|
|
OrderRefundData_order_lines
|
|
|
|
} from "../types/OrderRefundData";
|
|
|
|
|
|
|
|
export type OrderWithTotalAndTotalCaptured = Pick<
|
|
|
|
OrderRefundData_order,
|
|
|
|
"total" | "totalCaptured"
|
|
|
|
>;
|
|
|
|
|
|
|
|
export function getPreviouslyRefundedPrice(
|
|
|
|
order: OrderWithTotalAndTotalCaptured
|
|
|
|
): IMoney {
|
|
|
|
return (
|
|
|
|
order?.totalCaptured &&
|
|
|
|
order?.total?.gross &&
|
|
|
|
subtractMoney(order?.totalCaptured, order?.total?.gross)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-01-20 16:16:43 +00:00
|
|
|
const getItemPriceAndQuantity = ({
|
|
|
|
orderLines,
|
|
|
|
itemsQuantities,
|
|
|
|
id
|
|
|
|
}: {
|
|
|
|
orderLines: OrderDetails_order_lines[];
|
|
|
|
itemsQuantities: FormsetData<LineItemData, number>;
|
|
|
|
id: string;
|
|
|
|
}) => {
|
|
|
|
const { unitPrice } = orderLines.find(getById(id));
|
|
|
|
const selectedQuantity = itemsQuantities.find(getById(id))?.value;
|
|
|
|
|
|
|
|
return { selectedQuantity, unitPrice };
|
|
|
|
};
|
|
|
|
|
|
|
|
const selectItemPriceAndQuantity = (
|
|
|
|
order: OrderDetails_order,
|
|
|
|
{
|
|
|
|
fulfiledItemsQuantities,
|
|
|
|
unfulfiledItemsQuantities
|
|
|
|
}: Partial<OrderReturnFormData>,
|
|
|
|
id: string,
|
|
|
|
isFulfillment: boolean
|
|
|
|
) =>
|
|
|
|
isFulfillment
|
|
|
|
? getItemPriceAndQuantity({
|
|
|
|
id,
|
|
|
|
itemsQuantities: fulfiledItemsQuantities,
|
|
|
|
orderLines: getAllOrderFulfilledLines(order)
|
|
|
|
})
|
|
|
|
: getItemPriceAndQuantity({
|
|
|
|
id,
|
|
|
|
itemsQuantities: unfulfiledItemsQuantities,
|
|
|
|
orderLines: order.lines
|
|
|
|
});
|
|
|
|
|
|
|
|
export const getReplacedProductsAmount = (
|
|
|
|
order: OrderDetails_order,
|
|
|
|
{
|
|
|
|
itemsToBeReplaced,
|
|
|
|
unfulfiledItemsQuantities,
|
|
|
|
fulfiledItemsQuantities
|
|
|
|
}: Partial<OrderReturnFormData>
|
|
|
|
) => {
|
|
|
|
if (!order || !itemsToBeReplaced.length) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return itemsToBeReplaced.reduce(
|
|
|
|
(
|
|
|
|
resultAmount: number,
|
|
|
|
{ id, value: isItemToBeReplaced, data: { isFulfillment, isRefunded } }
|
|
|
|
) => {
|
|
|
|
if (!isItemToBeReplaced || isRefunded) {
|
|
|
|
return resultAmount;
|
|
|
|
}
|
|
|
|
|
|
|
|
const { unitPrice, selectedQuantity } = selectItemPriceAndQuantity(
|
|
|
|
order,
|
|
|
|
{ fulfiledItemsQuantities, unfulfiledItemsQuantities },
|
|
|
|
id,
|
|
|
|
isFulfillment
|
|
|
|
);
|
|
|
|
|
|
|
|
return resultAmount + unitPrice?.gross?.amount * selectedQuantity;
|
|
|
|
},
|
|
|
|
0
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export const getReturnSelectedProductsAmount = (
|
|
|
|
order: OrderDetails_order,
|
|
|
|
{ itemsToBeReplaced, unfulfiledItemsQuantities, fulfiledItemsQuantities }
|
|
|
|
) => {
|
|
|
|
if (!order) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
const unfulfilledItemsValue = getPartialProductsValue({
|
|
|
|
itemsQuantities: unfulfiledItemsQuantities,
|
|
|
|
itemsToBeReplaced,
|
|
|
|
orderLines: order.lines
|
|
|
|
});
|
|
|
|
|
|
|
|
const fulfiledItemsValue = getPartialProductsValue({
|
|
|
|
itemsQuantities: fulfiledItemsQuantities,
|
|
|
|
itemsToBeReplaced,
|
|
|
|
orderLines: getAllOrderFulfilledLines(order)
|
|
|
|
});
|
|
|
|
|
|
|
|
return unfulfilledItemsValue + fulfiledItemsValue;
|
|
|
|
};
|
|
|
|
|
|
|
|
const getPartialProductsValue = ({
|
|
|
|
orderLines,
|
|
|
|
itemsQuantities,
|
|
|
|
itemsToBeReplaced
|
|
|
|
}: {
|
|
|
|
itemsToBeReplaced: FormsetData<LineItemData, boolean>;
|
|
|
|
itemsQuantities: FormsetData<LineItemData, number>;
|
|
|
|
orderLines: OrderDetails_order_lines[];
|
|
|
|
}) =>
|
|
|
|
itemsQuantities.reduce((resultAmount, { id, value: quantity }) => {
|
|
|
|
const {
|
|
|
|
value: isItemToBeReplaced,
|
|
|
|
data: { isRefunded }
|
|
|
|
} = itemsToBeReplaced.find(getById(id));
|
|
|
|
|
|
|
|
if (quantity < 1 || isItemToBeReplaced || isRefunded) {
|
|
|
|
return resultAmount;
|
|
|
|
}
|
|
|
|
|
|
|
|
const { selectedQuantity, unitPrice } = getItemPriceAndQuantity({
|
|
|
|
id,
|
|
|
|
itemsQuantities,
|
|
|
|
orderLines
|
|
|
|
});
|
|
|
|
|
|
|
|
return resultAmount + unitPrice.gross.amount * selectedQuantity;
|
|
|
|
}, 0);
|
|
|
|
|
2020-12-01 13:13:05 +00:00
|
|
|
export function getRefundedLinesPriceSum(
|
|
|
|
lines: OrderRefundData_order_lines[],
|
2021-01-20 16:16:43 +00:00
|
|
|
refundedProductQuantities: FormsetData<null, string | number>
|
2020-12-01 13:13:05 +00:00
|
|
|
): number {
|
|
|
|
return lines?.reduce((sum, line) => {
|
|
|
|
const refundedLine = refundedProductQuantities.find(
|
|
|
|
refundedLine => refundedLine.id === line.id
|
|
|
|
);
|
|
|
|
return sum + line.unitPrice.gross.amount * Number(refundedLine?.value || 0);
|
|
|
|
}, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function getAllFulfillmentLinesPriceSum(
|
|
|
|
fulfillments: OrderRefundData_order_fulfillments[],
|
2021-01-20 16:16:43 +00:00
|
|
|
refundedFulfilledProductQuantities: FormsetData<null, string | number>
|
2020-12-01 13:13:05 +00:00
|
|
|
): number {
|
|
|
|
return fulfillments?.reduce((sum, fulfillment) => {
|
|
|
|
const fulfilmentLinesSum = fulfillment?.lines.reduce((sum, line) => {
|
|
|
|
const refundedLine = refundedFulfilledProductQuantities.find(
|
|
|
|
refundedLine => refundedLine.id === line.id
|
|
|
|
);
|
|
|
|
return (
|
|
|
|
sum +
|
|
|
|
line.orderLine.unitPrice.gross.amount * Number(refundedLine?.value || 0)
|
|
|
|
);
|
|
|
|
}, 0);
|
|
|
|
return sum + fulfilmentLinesSum;
|
|
|
|
}, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function mergeRepeatedOrderLines(
|
|
|
|
fulfillmentLines: OrderDetails_order_fulfillments_lines[]
|
|
|
|
) {
|
|
|
|
return fulfillmentLines.reduce((prev, curr) => {
|
|
|
|
const existingOrderLineIndex = prev.findIndex(
|
|
|
|
prevLine => prevLine.orderLine.id === curr.orderLine.id
|
|
|
|
);
|
|
|
|
|
|
|
|
if (existingOrderLineIndex === -1) {
|
|
|
|
prev.push(curr);
|
|
|
|
} else {
|
|
|
|
const existingOrderLine = prev[existingOrderLineIndex];
|
|
|
|
|
|
|
|
prev[existingOrderLineIndex] = {
|
|
|
|
...existingOrderLine,
|
|
|
|
quantity: existingOrderLine.quantity + curr.quantity
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
return prev;
|
|
|
|
}, Array<OrderDetails_order_fulfillments_lines>());
|
|
|
|
}
|