mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-08 14:48:18 +00:00
shipping line
This commit is contained in:
@@ -50,6 +50,14 @@ import type {
|
||||
RegisterShippingLineCompanyResult,
|
||||
ShippingLineCompany,
|
||||
} from "@/types/shippingLineCompany";
|
||||
import type {
|
||||
CreditInvoicePendingAction,
|
||||
GeneratedCreditInvoice,
|
||||
OutstandingTotals,
|
||||
PaginatedCreditInvoices,
|
||||
PaginatedShippingLineCredits,
|
||||
ShippingLineCreditStatus,
|
||||
} from "@/types/shippingLineCredit";
|
||||
import {
|
||||
RuleEngineListResult,
|
||||
RuleEngineRecord,
|
||||
@@ -163,6 +171,7 @@ import { containerTypesService } from "./container-types.service";
|
||||
import { containerService, type Container } from "./containerService";
|
||||
import { customersService } from "./customers.service";
|
||||
import { shippingLineCompaniesService } from "./shippingLineCompanies.service";
|
||||
import { shippingLineCreditsService } from "./shippingLineCredits.service";
|
||||
import { eimsService } from "./eims.service";
|
||||
import type { EimsInvoiceStatusView, EimsVerifyResult } from "@/types/eims";
|
||||
import { invoicesService } from "./invoices.service";
|
||||
@@ -2836,6 +2845,123 @@ export const api = {
|
||||
),
|
||||
},
|
||||
|
||||
shippingLineCredits: {
|
||||
summary: endpoint<{ shippingLineId?: string }, OutstandingTotals>(
|
||||
"shippingLineCredits",
|
||||
"summary",
|
||||
({ shippingLineId }) => shippingLineCreditsService.summary(shippingLineId),
|
||||
({ shippingLineId }) =>
|
||||
QUERY_KEYS.SHIPPING_LINE_CREDITS.summary(shippingLineId),
|
||||
),
|
||||
|
||||
list: endpoint<
|
||||
{
|
||||
page: number;
|
||||
pageSize: number;
|
||||
status?: ShippingLineCreditStatus;
|
||||
shippingLineId?: string;
|
||||
},
|
||||
PaginatedShippingLineCredits
|
||||
>(
|
||||
"shippingLineCredits",
|
||||
"list",
|
||||
(filter) => shippingLineCreditsService.list(filter),
|
||||
({ page, pageSize, status, shippingLineId }) =>
|
||||
QUERY_KEYS.SHIPPING_LINE_CREDITS.list(
|
||||
page,
|
||||
pageSize,
|
||||
status,
|
||||
shippingLineId,
|
||||
),
|
||||
),
|
||||
|
||||
generateInvoice: endpoint<
|
||||
{ creditIds: string[]; dueInDays?: number },
|
||||
GeneratedCreditInvoice
|
||||
>(
|
||||
"shippingLineCredits",
|
||||
"generateInvoice",
|
||||
({ creditIds, dueInDays }) =>
|
||||
shippingLineCreditsService.generateInvoice(creditIds, dueInDays),
|
||||
undefined,
|
||||
// Billing a batch changes ledger rows, the summary totals and (via the
|
||||
// draft invoice) the invoices list.
|
||||
() => [QUERY_KEYS.SHIPPING_LINE_CREDITS.ROOT, QUERY_KEYS.INVOICES.ROOT],
|
||||
),
|
||||
|
||||
listInvoices: endpoint<
|
||||
{
|
||||
page: number;
|
||||
pageSize: number;
|
||||
status?: string;
|
||||
shippingLineId?: string;
|
||||
},
|
||||
PaginatedCreditInvoices
|
||||
>(
|
||||
"shippingLineCredits",
|
||||
"listInvoices",
|
||||
(filter) => shippingLineCreditsService.listInvoices(filter),
|
||||
({ page, pageSize, status, shippingLineId }) =>
|
||||
QUERY_KEYS.SHIPPING_LINE_CREDITS.invoices(
|
||||
page,
|
||||
pageSize,
|
||||
status,
|
||||
shippingLineId,
|
||||
),
|
||||
),
|
||||
|
||||
pendingInvoiceActions: endpoint<
|
||||
{ invoiceIds: string[] },
|
||||
CreditInvoicePendingAction[]
|
||||
>(
|
||||
"shippingLineCredits",
|
||||
"pendingInvoiceActions",
|
||||
({ invoiceIds }) =>
|
||||
shippingLineCreditsService.pendingInvoiceActions(invoiceIds),
|
||||
({ invoiceIds }) =>
|
||||
[
|
||||
"shipping-line-credits",
|
||||
"pending-actions",
|
||||
[...invoiceIds].sort().join(","),
|
||||
] as const,
|
||||
),
|
||||
|
||||
requestInvoiceAction: endpoint<
|
||||
{
|
||||
invoiceId: string;
|
||||
action: "MARK_PAID" | "CANCEL";
|
||||
reason: string;
|
||||
paymentReference?: string;
|
||||
},
|
||||
CreditInvoicePendingAction
|
||||
>(
|
||||
"shippingLineCredits",
|
||||
"requestInvoiceAction",
|
||||
({ invoiceId, action, reason, paymentReference }) =>
|
||||
shippingLineCreditsService.requestInvoiceAction(
|
||||
invoiceId,
|
||||
action,
|
||||
reason,
|
||||
paymentReference,
|
||||
),
|
||||
undefined,
|
||||
() => [QUERY_KEYS.SHIPPING_LINE_CREDITS.ROOT],
|
||||
),
|
||||
|
||||
decideInvoiceAction: endpoint<
|
||||
{ approvalId: string; approve: boolean; note?: string },
|
||||
CreditInvoicePendingAction
|
||||
>(
|
||||
"shippingLineCredits",
|
||||
"decideInvoiceAction",
|
||||
({ approvalId, approve, note }) =>
|
||||
shippingLineCreditsService.decideInvoiceAction(approvalId, approve, note),
|
||||
undefined,
|
||||
// Approving executes a billing action, so both surfaces move.
|
||||
() => [QUERY_KEYS.SHIPPING_LINE_CREDITS.ROOT, QUERY_KEYS.INVOICES.ROOT],
|
||||
),
|
||||
},
|
||||
|
||||
customers: {
|
||||
stats: endpoint<Record<string, never>, CompanyStats>(
|
||||
"customers",
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
import { api as apiClient } from "@/auth/http";
|
||||
import { URL_CONSTANTS } from "@/constants/URLS";
|
||||
import type {
|
||||
CreditInvoicePendingAction,
|
||||
GeneratedCreditInvoice,
|
||||
OutstandingTotals,
|
||||
PaginatedCreditInvoices,
|
||||
PaginatedShippingLineCredits,
|
||||
ShippingLineCreditStatus,
|
||||
} from "@/types/shippingLineCredit";
|
||||
|
||||
export interface ShippingLineCreditListFilter {
|
||||
page?: number;
|
||||
pageSize?: number;
|
||||
status?: ShippingLineCreditStatus;
|
||||
/** Narrow to one line; omit for all lines. */
|
||||
shippingLineId?: string;
|
||||
}
|
||||
|
||||
export const shippingLineCreditsService = {
|
||||
/** Outstanding totals — every line, or one line when an id is given. */
|
||||
summary(shippingLineId?: string): Promise<OutstandingTotals> {
|
||||
return apiClient
|
||||
.get<OutstandingTotals>(URL_CONSTANTS.SHIPPING_LINE_CREDITS.SUMMARY, {
|
||||
params: shippingLineId ? { shippingLineId } : {},
|
||||
})
|
||||
.then((r) => r.data);
|
||||
},
|
||||
|
||||
/** The whole credit ledger, newest first, optionally filtered. */
|
||||
list(
|
||||
filter: ShippingLineCreditListFilter = {},
|
||||
): Promise<PaginatedShippingLineCredits> {
|
||||
const { page = 1, pageSize = 20, status, shippingLineId } = filter;
|
||||
return apiClient
|
||||
.get<PaginatedShippingLineCredits>(
|
||||
URL_CONSTANTS.SHIPPING_LINE_CREDITS.BASE,
|
||||
{
|
||||
params: {
|
||||
page,
|
||||
pageSize,
|
||||
...(status ? { status } : {}),
|
||||
...(shippingLineId ? { shippingLineId } : {}),
|
||||
},
|
||||
},
|
||||
)
|
||||
.then((r) => r.data);
|
||||
},
|
||||
|
||||
/**
|
||||
* Bill a batch of unbilled credits as one invoice. The API enforces that all
|
||||
* credits belong to one shipping line and share one currency.
|
||||
*/
|
||||
generateInvoice(
|
||||
creditIds: string[],
|
||||
dueInDays?: number,
|
||||
): Promise<GeneratedCreditInvoice> {
|
||||
return apiClient
|
||||
.post<GeneratedCreditInvoice>(URL_CONSTANTS.SHIPPING_LINE_CREDITS.INVOICE, {
|
||||
creditIds,
|
||||
...(dueInDays ? { dueInDays } : {}),
|
||||
})
|
||||
.then((r) => r.data);
|
||||
},
|
||||
|
||||
/** Credit invoices with any pending manual-action request attached. */
|
||||
listInvoices(filter: {
|
||||
page?: number;
|
||||
pageSize?: number;
|
||||
status?: string;
|
||||
shippingLineId?: string;
|
||||
} = {}): Promise<PaginatedCreditInvoices> {
|
||||
const { page = 1, pageSize = 20, status, shippingLineId } = filter;
|
||||
return apiClient
|
||||
.get<PaginatedCreditInvoices>(URL_CONSTANTS.SHIPPING_LINE_CREDITS.INVOICES, {
|
||||
params: {
|
||||
page,
|
||||
pageSize,
|
||||
...(status ? { status } : {}),
|
||||
...(shippingLineId ? { shippingLineId } : {}),
|
||||
},
|
||||
})
|
||||
.then((r) => r.data);
|
||||
},
|
||||
|
||||
/** Undecided manual-action requests for a batch of invoice ids. */
|
||||
pendingInvoiceActions(
|
||||
invoiceIds: string[],
|
||||
): Promise<CreditInvoicePendingAction[]> {
|
||||
if (!invoiceIds.length) return Promise.resolve([]);
|
||||
return apiClient
|
||||
.get<CreditInvoicePendingAction[]>(
|
||||
`${URL_CONSTANTS.SHIPPING_LINE_CREDITS.BASE}/invoice-actions/pending`,
|
||||
{ params: { invoiceIds: invoiceIds.join(",") } },
|
||||
)
|
||||
.then((r) => r.data);
|
||||
},
|
||||
|
||||
/** Maker step: raise a mark-paid or cancel request on a credit invoice. */
|
||||
requestInvoiceAction(
|
||||
invoiceId: string,
|
||||
action: "MARK_PAID" | "CANCEL",
|
||||
reason: string,
|
||||
paymentReference?: string,
|
||||
): Promise<CreditInvoicePendingAction> {
|
||||
const url =
|
||||
action === "MARK_PAID"
|
||||
? URL_CONSTANTS.SHIPPING_LINE_CREDITS.MARK_PAID_REQUEST(invoiceId)
|
||||
: URL_CONSTANTS.SHIPPING_LINE_CREDITS.CANCEL_REQUEST(invoiceId);
|
||||
return apiClient
|
||||
.post<CreditInvoicePendingAction>(url, {
|
||||
reason,
|
||||
...(paymentReference ? { paymentReference } : {}),
|
||||
})
|
||||
.then((r) => r.data);
|
||||
},
|
||||
|
||||
/** Decision step: approve (executes) or reject a pending request. */
|
||||
decideInvoiceAction(
|
||||
approvalId: string,
|
||||
approve: boolean,
|
||||
note?: string,
|
||||
): Promise<CreditInvoicePendingAction> {
|
||||
const url = approve
|
||||
? URL_CONSTANTS.SHIPPING_LINE_CREDITS.APPROVE_ACTION(approvalId)
|
||||
: URL_CONSTANTS.SHIPPING_LINE_CREDITS.REJECT_ACTION(approvalId);
|
||||
return apiClient
|
||||
.post<CreditInvoicePendingAction>(url, note ? { note } : {})
|
||||
.then((r) => r.data);
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user