@vulog/aima-business 1.2.39
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/dist/index.cjs +668 -0
- package/dist/index.d.cts +346 -0
- package/dist/index.d.mts +346 -0
- package/dist/index.mjs +609 -0
- package/package.json +42 -0
- package/src/addBusinessCredit.ts +31 -0
- package/src/addStripePayment.ts +18 -0
- package/src/addTripNote.test.ts +67 -0
- package/src/addTripNote.ts +30 -0
- package/src/addUserToBusiness.test.ts +74 -0
- package/src/addUserToBusiness.ts +49 -0
- package/src/archiveBusinessProfile.ts +28 -0
- package/src/bulkAddBusinessUsers.ts +27 -0
- package/src/businessDelegatedAdmin.test.ts +68 -0
- package/src/businessDelegatedAdmin.ts +32 -0
- package/src/businessOwner.test.ts +68 -0
- package/src/businessOwner.ts +32 -0
- package/src/chargeBusinessProduct.ts +31 -0
- package/src/createBusiness.test.ts +54 -0
- package/src/createBusiness.ts +23 -0
- package/src/createBusinessCostCenter.test.ts +61 -0
- package/src/createBusinessCostCenter.ts +34 -0
- package/src/deactivateBusinessProfile.ts +22 -0
- package/src/deleteBusinessCostCenter.test.ts +45 -0
- package/src/deleteBusinessCostCenter.ts +23 -0
- package/src/deleteInvitationRequest.test.ts +45 -0
- package/src/deleteInvitationRequest.ts +13 -0
- package/src/getBillingGroups.ts +9 -0
- package/src/getBusinessById.test.ts +47 -0
- package/src/getBusinessById.ts +15 -0
- package/src/getBusinessContacts.ts +17 -0
- package/src/getBusinessCostCenterById.ts +27 -0
- package/src/getBusinessCostCenters.ts +18 -0
- package/src/getBusinessInviteLink.ts +17 -0
- package/src/getBusinessInvoiceProducts.ts +24 -0
- package/src/getBusinessInvoiceTrips.ts +20 -0
- package/src/getBusinessInvoices.test.ts +92 -0
- package/src/getBusinessInvoices.ts +43 -0
- package/src/getBusinessPaymentDetails.ts +20 -0
- package/src/getBusinessProducts.ts +9 -0
- package/src/getBusinessTripById.ts +15 -0
- package/src/getBusinessUserById.ts +26 -0
- package/src/getBusinessUserGlobalById.ts +15 -0
- package/src/getBusinessUsers.test.ts +70 -0
- package/src/getBusinessUsers.ts +43 -0
- package/src/getBusinessWallet.test.ts +46 -0
- package/src/getBusinessWallet.ts +17 -0
- package/src/getBusinesses.test.ts +133 -0
- package/src/getBusinesses.ts +36 -0
- package/src/getEntityBalance.ts +17 -0
- package/src/getEntityProducts.ts +15 -0
- package/src/getEntityTrips.ts +13 -0
- package/src/getEntityTripsCost.ts +17 -0
- package/src/getInvitationRequest.test.ts +46 -0
- package/src/getInvitationRequest.ts +17 -0
- package/src/getInvoicePdf.test.ts +62 -0
- package/src/getInvoicePdf.ts +16 -0
- package/src/getInvoiceRefundNote.ts +17 -0
- package/src/getInvoiceRefundableAmount.ts +20 -0
- package/src/getOngoingTripNotes.ts +17 -0
- package/src/getOngoingTrips.test.ts +43 -0
- package/src/getOngoingTrips.ts +9 -0
- package/src/getStripePublishableKey.ts +9 -0
- package/src/getStripeSetup.ts +17 -0
- package/src/index.ts +58 -0
- package/src/inviteBusinessUser.ts +31 -0
- package/src/listBusinessUsersGlobal.test.ts +65 -0
- package/src/listBusinessUsersGlobal.ts +26 -0
- package/src/redeemBusinessPromoCode.ts +18 -0
- package/src/refundInvoice.test.ts +72 -0
- package/src/refundInvoice.ts +33 -0
- package/src/refundInvoiceAmount.ts +20 -0
- package/src/searchBusinessUsersByName.ts +27 -0
- package/src/searchBusinessUsersGlobal.ts +18 -0
- package/src/sendBusinessIban.ts +29 -0
- package/src/setInvoiceExternalPayment.ts +33 -0
- package/src/types.ts +163 -0
- package/src/updateBusiness.test.ts +65 -0
- package/src/updateBusiness.ts +35 -0
- package/src/updateBusinessCostCenter.ts +41 -0
- package/src/updateBusinessProfileStatus.ts +22 -0
- package/src/updateBusinessUserProfile.ts +51 -0
- package/src/updateInvoiceStatus.test.ts +54 -0
- package/src/updateInvoiceStatus.ts +19 -0
- package/tsconfig.json +9 -0
- package/tsdown.config.ts +8 -0
- package/vitest.config.ts +1 -0
package/src/types.ts
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/** Represents a business entity */
|
|
2
|
+
export type Business = {
|
|
3
|
+
/** Unique identifier */
|
|
4
|
+
id: string;
|
|
5
|
+
/** Business name */
|
|
6
|
+
name: string;
|
|
7
|
+
/** Business status */
|
|
8
|
+
status: string;
|
|
9
|
+
[key: string]: any;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/** Represents a contact within a business */
|
|
13
|
+
export type BusinessContact = {
|
|
14
|
+
/** Contact identifier */
|
|
15
|
+
id: string;
|
|
16
|
+
/** Contact name */
|
|
17
|
+
name: string;
|
|
18
|
+
/** Contact email */
|
|
19
|
+
email: string;
|
|
20
|
+
[key: string]: any;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/** Represents a cost center within a business */
|
|
24
|
+
export type CostCenter = {
|
|
25
|
+
/** Unique identifier */
|
|
26
|
+
id: string;
|
|
27
|
+
/** Cost center name */
|
|
28
|
+
name: string;
|
|
29
|
+
/** Parent business identifier */
|
|
30
|
+
businessId: string;
|
|
31
|
+
[key: string]: any;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/** Represents payment details for a business */
|
|
35
|
+
export type BusinessPaymentDetails = {
|
|
36
|
+
/** Payment method type */
|
|
37
|
+
paymentMethod: string;
|
|
38
|
+
[key: string]: any;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/** Represents a user linked to a business */
|
|
42
|
+
export type BusinessUser = {
|
|
43
|
+
/** User identifier */
|
|
44
|
+
userId: string;
|
|
45
|
+
/** Business identifier */
|
|
46
|
+
businessId: string;
|
|
47
|
+
/** User role within the business */
|
|
48
|
+
role: string;
|
|
49
|
+
[key: string]: any;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/** Represents an invitation link for a business */
|
|
53
|
+
export type BusinessInviteLink = {
|
|
54
|
+
/** Invitation URL */
|
|
55
|
+
url: string;
|
|
56
|
+
[key: string]: any;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/** Represents entity balance information */
|
|
60
|
+
export type EntityBalance = {
|
|
61
|
+
/** Entity identifier */
|
|
62
|
+
entityId: string;
|
|
63
|
+
/** Current balance */
|
|
64
|
+
balance: number;
|
|
65
|
+
[key: string]: any;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/** Represents the total cost of trips for an entity */
|
|
69
|
+
export type EntityTripsCost = {
|
|
70
|
+
/** Total cost */
|
|
71
|
+
totalCost: number;
|
|
72
|
+
[key: string]: any;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/** Represents a billing group in the business context */
|
|
76
|
+
export type BusinessBillingGroup = {
|
|
77
|
+
/** Group identifier */
|
|
78
|
+
id: string;
|
|
79
|
+
/** Group name */
|
|
80
|
+
name: string;
|
|
81
|
+
[key: string]: any;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/** Represents a Stripe setup response */
|
|
85
|
+
export type StripeSetup = {
|
|
86
|
+
/** Client secret for Stripe */
|
|
87
|
+
clientSecret: string;
|
|
88
|
+
[key: string]: any;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/** Represents Stripe configuration */
|
|
92
|
+
export type StripeConfig = {
|
|
93
|
+
/** Stripe publishable key */
|
|
94
|
+
publishableKey: string;
|
|
95
|
+
[key: string]: any;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/** Represents a business invoice */
|
|
99
|
+
export type BusinessInvoice = {
|
|
100
|
+
/** Invoice identifier */
|
|
101
|
+
id: string;
|
|
102
|
+
/** Invoice amount */
|
|
103
|
+
amount: number;
|
|
104
|
+
/** Invoice status */
|
|
105
|
+
status: string;
|
|
106
|
+
[key: string]: any;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
/** Represents the refund note for an invoice */
|
|
110
|
+
export type InvoiceRefundNote = {
|
|
111
|
+
[key: string]: any;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
/** Represents the refundable amount for an invoice */
|
|
115
|
+
export type InvoiceRefundableAmount = {
|
|
116
|
+
/** Invoice identifier */
|
|
117
|
+
invoiceId: string;
|
|
118
|
+
/** Refundable amount */
|
|
119
|
+
refundableAmount: number;
|
|
120
|
+
[key: string]: any;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
/** Represents a business trip */
|
|
124
|
+
export type BusinessTrip = {
|
|
125
|
+
/** Trip identifier */
|
|
126
|
+
tripId: string;
|
|
127
|
+
[key: string]: any;
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
/** Represents a note on a trip */
|
|
131
|
+
export type TripNote = {
|
|
132
|
+
/** Note identifier */
|
|
133
|
+
id: string;
|
|
134
|
+
/** Note content */
|
|
135
|
+
content: string;
|
|
136
|
+
[key: string]: any;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
/** Represents a product in the business context */
|
|
140
|
+
export type BusinessProduct = {
|
|
141
|
+
/** Product identifier */
|
|
142
|
+
id: string;
|
|
143
|
+
/** Product name */
|
|
144
|
+
name: string;
|
|
145
|
+
[key: string]: any;
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
/** Represents an invitation request */
|
|
149
|
+
export type InvitationRequest = {
|
|
150
|
+
/** Invitation request identifier */
|
|
151
|
+
id: string;
|
|
152
|
+
[key: string]: any;
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
/** Represents a business wallet */
|
|
156
|
+
export type BusinessWallet = {
|
|
157
|
+
[key: string]: any;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
/** Represents a business user profile */
|
|
161
|
+
export type BusinessUserProfile = {
|
|
162
|
+
[key: string]: any;
|
|
163
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { describe, test, vi, expect, beforeEach } from 'vitest';
|
|
2
|
+
import { Client } from '@vulog/aima-client';
|
|
3
|
+
import { updateBusiness, UpdateBusinessBody } from './updateBusiness';
|
|
4
|
+
|
|
5
|
+
describe('updateBusiness', () => {
|
|
6
|
+
const putMock = vi.fn();
|
|
7
|
+
const client = {
|
|
8
|
+
put: putMock,
|
|
9
|
+
clientOptions: {
|
|
10
|
+
fleetId: 'FLEET_ID',
|
|
11
|
+
},
|
|
12
|
+
} as unknown as Client;
|
|
13
|
+
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
vi.clearAllMocks();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const BUSINESS_ID = '018ab2b6-71b2-4c76-90bd-6e8d3f268618';
|
|
19
|
+
|
|
20
|
+
test('should update a business with valid body', async () => {
|
|
21
|
+
const body: UpdateBusinessBody = { name: 'Updated Corp' };
|
|
22
|
+
const mockResponse = { id: BUSINESS_ID, name: 'Updated Corp', status: 'ACTIVE' };
|
|
23
|
+
putMock.mockResolvedValueOnce({ data: mockResponse });
|
|
24
|
+
|
|
25
|
+
const result = await updateBusiness(client, BUSINESS_ID, body);
|
|
26
|
+
|
|
27
|
+
expect(result).toEqual(mockResponse);
|
|
28
|
+
expect(putMock).toHaveBeenCalledWith(
|
|
29
|
+
`/boapi/proxy/business/fleets/FLEET_ID/business/${BUSINESS_ID}`,
|
|
30
|
+
body
|
|
31
|
+
);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test('should update a business with empty body (no fields)', async () => {
|
|
35
|
+
const body: UpdateBusinessBody = {};
|
|
36
|
+
const mockResponse = { id: BUSINESS_ID, name: 'Existing Corp', status: 'ACTIVE' };
|
|
37
|
+
putMock.mockResolvedValueOnce({ data: mockResponse });
|
|
38
|
+
|
|
39
|
+
const result = await updateBusiness(client, BUSINESS_ID, body);
|
|
40
|
+
|
|
41
|
+
expect(result).toEqual(mockResponse);
|
|
42
|
+
expect(putMock).toHaveBeenCalledWith(
|
|
43
|
+
`/boapi/proxy/business/fleets/FLEET_ID/business/${BUSINESS_ID}`,
|
|
44
|
+
body
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test('should throw for empty businessId', async () => {
|
|
49
|
+
await expect(updateBusiness(client, '', { name: 'Test' })).rejects.toThrow(TypeError);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('should throw for non-uuid businessId', async () => {
|
|
53
|
+
await expect(updateBusiness(client, 'not-a-uuid', { name: 'Test' })).rejects.toThrow(TypeError);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test('should throw for empty name string', async () => {
|
|
57
|
+
const body: UpdateBusinessBody = { name: '' };
|
|
58
|
+
await expect(updateBusiness(client, BUSINESS_ID, body)).rejects.toThrow(TypeError);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('should throw for name exceeding 255 characters', async () => {
|
|
62
|
+
const body: UpdateBusinessBody = { name: 'a'.repeat(256) };
|
|
63
|
+
await expect(updateBusiness(client, BUSINESS_ID, body)).rejects.toThrow(TypeError);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Client } from '@vulog/aima-client';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
import { Business } from './types';
|
|
5
|
+
|
|
6
|
+
export type UpdateBusinessBody = {
|
|
7
|
+
name?: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const updateBusinessBodySchema = z.object({
|
|
11
|
+
name: z.string().trim().min(1).max(255).optional(),
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export const updateBusiness = async (
|
|
15
|
+
client: Client,
|
|
16
|
+
businessId: string,
|
|
17
|
+
body: UpdateBusinessBody
|
|
18
|
+
): Promise<Business> => {
|
|
19
|
+
const parsedId = z.string().trim().min(1).uuid().safeParse(businessId);
|
|
20
|
+
if (!parsedId.success) {
|
|
21
|
+
throw new TypeError('Invalid args', { cause: parsedId.error.issues });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const result = updateBusinessBodySchema.safeParse(body);
|
|
25
|
+
if (!result.success) {
|
|
26
|
+
throw new TypeError('Invalid args', { cause: result.error.issues });
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return client
|
|
30
|
+
.put<Business>(
|
|
31
|
+
`/boapi/proxy/business/fleets/${client.clientOptions.fleetId}/business/${parsedId.data}`,
|
|
32
|
+
result.data
|
|
33
|
+
)
|
|
34
|
+
.then(({ data }) => data);
|
|
35
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Client } from '@vulog/aima-client';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
import { CostCenter } from './types';
|
|
5
|
+
|
|
6
|
+
export type UpdateCostCenterBody = {
|
|
7
|
+
name?: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const uuidSchema = z.string().trim().min(1).uuid();
|
|
11
|
+
|
|
12
|
+
const bodySchema = z.object({
|
|
13
|
+
name: z.string().trim().min(1).max(255).optional(),
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
export const updateBusinessCostCenter = async (
|
|
17
|
+
client: Client,
|
|
18
|
+
businessId: string,
|
|
19
|
+
costCenterId: string,
|
|
20
|
+
body: UpdateCostCenterBody
|
|
21
|
+
): Promise<CostCenter> => {
|
|
22
|
+
const parsedBusinessId = uuidSchema.safeParse(businessId);
|
|
23
|
+
const parsedCostCenterId = uuidSchema.safeParse(costCenterId);
|
|
24
|
+
if (!parsedBusinessId.success || !parsedCostCenterId.success) {
|
|
25
|
+
throw new TypeError('Invalid args', {
|
|
26
|
+
cause: [...(parsedBusinessId.error?.issues ?? []), ...(parsedCostCenterId.error?.issues ?? [])],
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const result = bodySchema.safeParse(body);
|
|
31
|
+
if (!result.success) {
|
|
32
|
+
throw new TypeError('Invalid args', { cause: result.error.issues });
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return client
|
|
36
|
+
.put<CostCenter>(
|
|
37
|
+
`/boapi/proxy/business/fleets/${client.clientOptions.fleetId}/business/${parsedBusinessId.data}/costcenter/${parsedCostCenterId.data}`,
|
|
38
|
+
result.data
|
|
39
|
+
)
|
|
40
|
+
.then(({ data }) => data);
|
|
41
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Client } from '@vulog/aima-client';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
const schema = z.object({
|
|
5
|
+
businessId: z.string().trim().min(1).uuid(),
|
|
6
|
+
status: z.string().trim().min(1),
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
export const updateBusinessProfileStatus = async (
|
|
10
|
+
client: Client,
|
|
11
|
+
businessId: string,
|
|
12
|
+
status: string
|
|
13
|
+
): Promise<void> => {
|
|
14
|
+
const result = schema.safeParse({ businessId, status });
|
|
15
|
+
if (!result.success) {
|
|
16
|
+
throw new TypeError('Invalid args', { cause: result.error.issues });
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
await client.put<void>(
|
|
20
|
+
`/boapi/proxy/business/fleets/${client.clientOptions.fleetId}/business/${result.data.businessId}/profile/user/profile/status/${result.data.status}`
|
|
21
|
+
);
|
|
22
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Client } from '@vulog/aima-client';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
import { BusinessUserProfile } from './types';
|
|
5
|
+
|
|
6
|
+
export type UpdateBusinessUserProfileBody = {
|
|
7
|
+
email?: string;
|
|
8
|
+
emailConsent?: boolean;
|
|
9
|
+
costCenterId?: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const uuidSchema = z.string().trim().min(1).uuid();
|
|
13
|
+
|
|
14
|
+
const bodySchema = z.object({
|
|
15
|
+
email: z.string().trim().email().optional(),
|
|
16
|
+
emailConsent: z.boolean().optional(),
|
|
17
|
+
costCenterId: z.string().trim().min(1).uuid().optional(),
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export const updateBusinessUserProfile = async (
|
|
21
|
+
client: Client,
|
|
22
|
+
businessId: string,
|
|
23
|
+
userId: string,
|
|
24
|
+
profileId: string,
|
|
25
|
+
body: UpdateBusinessUserProfileBody
|
|
26
|
+
): Promise<BusinessUserProfile> => {
|
|
27
|
+
const parsedBusinessId = uuidSchema.safeParse(businessId);
|
|
28
|
+
const parsedUserId = uuidSchema.safeParse(userId);
|
|
29
|
+
const parsedProfileId = uuidSchema.safeParse(profileId);
|
|
30
|
+
if (!parsedBusinessId.success || !parsedUserId.success || !parsedProfileId.success) {
|
|
31
|
+
throw new TypeError('Invalid args', {
|
|
32
|
+
cause: [
|
|
33
|
+
...(parsedBusinessId.error?.issues ?? []),
|
|
34
|
+
...(parsedUserId.error?.issues ?? []),
|
|
35
|
+
...(parsedProfileId.error?.issues ?? []),
|
|
36
|
+
],
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const result = bodySchema.safeParse(body);
|
|
41
|
+
if (!result.success) {
|
|
42
|
+
throw new TypeError('Invalid args', { cause: result.error.issues });
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return client
|
|
46
|
+
.put<BusinessUserProfile>(
|
|
47
|
+
`/boapi/proxy/business/fleets/${client.clientOptions.fleetId}/business/${parsedBusinessId.data}/user/${parsedUserId.data}/profile/${parsedProfileId.data}`,
|
|
48
|
+
result.data
|
|
49
|
+
)
|
|
50
|
+
.then(({ data }) => data);
|
|
51
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { describe, test, vi, expect, beforeEach } from 'vitest';
|
|
2
|
+
import { Client } from '@vulog/aima-client';
|
|
3
|
+
import { updateInvoiceStatus } from './updateInvoiceStatus';
|
|
4
|
+
|
|
5
|
+
describe('updateInvoiceStatus', () => {
|
|
6
|
+
const postMock = vi.fn();
|
|
7
|
+
const client = {
|
|
8
|
+
post: postMock,
|
|
9
|
+
clientOptions: { fleetId: 'FLEET_ID' },
|
|
10
|
+
} as unknown as Client;
|
|
11
|
+
|
|
12
|
+
const INVOICE_ID = '018ab2b6-71b2-4c76-90bd-6e8d3f268618';
|
|
13
|
+
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
vi.clearAllMocks();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test('should update invoice status successfully', async () => {
|
|
19
|
+
postMock.mockResolvedValueOnce({ data: undefined });
|
|
20
|
+
|
|
21
|
+
const result = await updateInvoiceStatus(client, INVOICE_ID, 'PAID');
|
|
22
|
+
|
|
23
|
+
expect(result).toBeUndefined();
|
|
24
|
+
expect(postMock).toHaveBeenCalledWith(
|
|
25
|
+
`/boapi/proxy/business/fleets/FLEET_ID/invoices/${INVOICE_ID}/status/PAID`,
|
|
26
|
+
{}
|
|
27
|
+
);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test('should throw for empty invoiceId', async () => {
|
|
31
|
+
await expect(updateInvoiceStatus(client, '', 'PAID')).rejects.toThrow(TypeError);
|
|
32
|
+
expect(postMock).not.toHaveBeenCalled();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test('should throw for non-uuid invoiceId', async () => {
|
|
36
|
+
await expect(updateInvoiceStatus(client, 'not-a-uuid', 'PAID')).rejects.toThrow(TypeError);
|
|
37
|
+
expect(postMock).not.toHaveBeenCalled();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test('should throw for empty status', async () => {
|
|
41
|
+
await expect(updateInvoiceStatus(client, INVOICE_ID, '')).rejects.toThrow(TypeError);
|
|
42
|
+
expect(postMock).not.toHaveBeenCalled();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test('should throw for whitespace-only status', async () => {
|
|
46
|
+
await expect(updateInvoiceStatus(client, INVOICE_ID, ' ')).rejects.toThrow(TypeError);
|
|
47
|
+
expect(postMock).not.toHaveBeenCalled();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test('should throw for whitespace-only invoiceId', async () => {
|
|
51
|
+
await expect(updateInvoiceStatus(client, ' ', 'PAID')).rejects.toThrow(TypeError);
|
|
52
|
+
expect(postMock).not.toHaveBeenCalled();
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Client } from '@vulog/aima-client';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
const schema = z.object({
|
|
5
|
+
invoiceId: z.string().trim().min(1).uuid(),
|
|
6
|
+
status: z.string().trim().min(1),
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
export const updateInvoiceStatus = async (client: Client, invoiceId: string, status: string): Promise<void> => {
|
|
10
|
+
const result = schema.safeParse({ invoiceId, status });
|
|
11
|
+
if (!result.success) {
|
|
12
|
+
throw new TypeError('Invalid args', { cause: result.error.issues });
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
await client.post<void>(
|
|
16
|
+
`/boapi/proxy/business/fleets/${client.clientOptions.fleetId}/invoices/${result.data.invoiceId}/status/${result.data.status}`,
|
|
17
|
+
{}
|
|
18
|
+
);
|
|
19
|
+
};
|
package/tsconfig.json
ADDED
package/tsdown.config.ts
ADDED
package/vitest.config.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '../../vitest.config.base.ts';
|