Skip to content

Commit b96143c

Browse files
committed
feat: implement BillsV4 endpoint and tests
1 parent bb905a1 commit b96143c

File tree

4 files changed

+429
-0
lines changed

4 files changed

+429
-0
lines changed

src/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import Users from "./resources/Users";
1616
import Items from "./resources/Items";
1717
import Invoices from "./resources/Invoices";
1818
import Currencies from "./resources/Currencies";
19+
import BillsV4 from "./resources/BillsV4";
1920

2021
export * from "./interfaces/BillsStatic";
2122
export * from "./interfaces/BusinessActivitiesStatic";
@@ -39,6 +40,7 @@ export * from "./interfaces/ItemsStatic";
3940
export * from "./interfaces/InvoicesStatic";
4041
export * from "./interfaces/PositionStatic";
4142
export * from "./interfaces/CurrenciesStatic";
43+
export * from "./interfaces/BillsV4Static";
4244

4345
export default class Bexio {
4446
private token: string;
@@ -57,6 +59,11 @@ export default class Bexio {
5759
// Sales Order Management
5860
public orders: Orders;
5961
public expenses: Expenses;
62+
public billsV4: BillsV4;
63+
64+
/**
65+
* @deprecated Use BillsV4 instead
66+
*/
6067
public bills: Bills;
6168

6269
// Projects
@@ -95,6 +102,7 @@ export default class Bexio {
95102
this.projectStatuses = new ProjectStatuses(this.token);
96103
this.projectTypes = new ProjectTypes(this.token);
97104
this.expenses = new Expenses(this.token);
105+
this.billsV4 = new BillsV4(this.token);
98106
this.bills = new Bills(this.token);
99107
this.timetrackings = new Timetrackings(this.token);
100108
this.timetrackingStatuses = new TimetrackingStatuses(this.token);

src/interfaces/BillsV4Static.ts

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
export namespace BillsV4Static {
2+
export interface Bill {
3+
id: string; // uuid, required
4+
document_no: string; // required, 1..255 chars
5+
title?: string; // 1..80 chars
6+
status: BillStatus; // required, enum
7+
firstname_suffix?: string; // 1..80 chars
8+
lastname_company: string; // required, 1..80 chars
9+
created_at: string; // required, date-time
10+
vendor_ref?: string; // 1..255 chars
11+
pending_amount?: number; // double
12+
currency_code: string; // required, 1..20 chars
13+
net?: number; // double, calculated from line_items and discounts
14+
gross?: number; // double, calculated from line_items and discounts
15+
bill_date: string; // required, date
16+
due_date: string; // required, date
17+
overdue: boolean; // required
18+
booking_account_ids: number[]; // required, array of int32
19+
attachment_ids: string[]; // required, array of uuid
20+
}
21+
22+
export interface BillFull extends Bill {
23+
supplier_id: number;
24+
contact_partner_id: number;
25+
amount_man: number;
26+
amount_calc: number;
27+
manual_amount: boolean;
28+
exchange_rate: number;
29+
base_currency_code: string;
30+
item_net: boolean;
31+
split_into_line_items: boolean;
32+
purchase_order_id?: number;
33+
base_currency_amount: number;
34+
qr_bill_information?: string;
35+
address: Address;
36+
line_items: LineItem[];
37+
discounts: Discount[];
38+
payment?: Payment;
39+
note?: string;
40+
}
41+
42+
export interface Address {
43+
title?: string;
44+
salutation?: string;
45+
firstname_suffix?: string;
46+
lastname_company: string;
47+
address_line?: string;
48+
postcode?: string;
49+
city?: string;
50+
country_code?: string;
51+
main_contact_id?: number;
52+
contact_address_id?: number;
53+
type: "PRIVATE" | "COMPANY";
54+
}
55+
56+
export interface LineItem {
57+
position: number;
58+
title?: string;
59+
tax_id?: number;
60+
amount: number;
61+
booking_account_id?: number;
62+
}
63+
64+
export interface Discount {
65+
position: number;
66+
amount: number;
67+
}
68+
69+
export interface Payment {
70+
type: PaymentType;
71+
bank_account_id?: number;
72+
fee?: PaymentFee;
73+
execution_date: string;
74+
exchange_rate?: number;
75+
amount: number;
76+
account_no?: string;
77+
iban?: string;
78+
name?: string;
79+
address?: string;
80+
street?: string;
81+
house_no?: string;
82+
postcode?: string;
83+
city?: string;
84+
country_code?: string;
85+
message?: string;
86+
booking_text?: string;
87+
salary_payment?: boolean;
88+
reference_no?: string;
89+
}
90+
91+
export interface BillCreate {
92+
supplier_id: number;
93+
vendor_ref?: string;
94+
title?: string;
95+
contact_partner_id: number;
96+
bill_date: string;
97+
due_date: string;
98+
amount_man?: number;
99+
amount_calc?: number;
100+
manual_amount: boolean;
101+
currency_code: string;
102+
exchange_rate?: number;
103+
base_currency_amount?: number;
104+
item_net: boolean;
105+
purchase_order_id?: number;
106+
qr_bill_information?: string;
107+
attachment_ids: string[];
108+
address: Address;
109+
line_items: LineItem[];
110+
discounts: Discount[];
111+
payment?: Payment;
112+
salary_payment?: boolean;
113+
reference_no?: string;
114+
note?: string;
115+
}
116+
117+
export interface BillOverwrite {
118+
document_no?: string;
119+
title?: string;
120+
supplier_id: number;
121+
vendor_ref?: string;
122+
contact_partner_id: number;
123+
bill_date: string;
124+
due_date: string;
125+
amount_man?: number;
126+
amount_calc?: number;
127+
manual_amount: boolean;
128+
currency_code: string;
129+
exchange_rate?: number;
130+
item_net: boolean;
131+
split_into_line_items: boolean;
132+
base_currency_amount?: number;
133+
attachment_ids: string[];
134+
address: Address;
135+
line_items: LineItem[];
136+
discounts: Discount[];
137+
payment?: Payment;
138+
}
139+
140+
export enum SearchParameters {
141+
document_no = "document_no",
142+
title = "title",
143+
vendor_ref = "vendor_ref",
144+
currency_code = "currency_code",
145+
lastname_company = "lastname_company",
146+
firstname_suffix = "firstname_suffix",
147+
}
148+
149+
export enum BillStatusUpdate {
150+
DRAFT = "DRAFT",
151+
BOOKED = "BOOKED",
152+
}
153+
154+
export enum BillAction {
155+
DUPLICATE = "DUPLICATE",
156+
}
157+
158+
export interface ListOptions {
159+
limit?: number;
160+
page?: number;
161+
order?: "asc" | "desc";
162+
sort?: string;
163+
search_term?: string;
164+
"fields[]"?: string[];
165+
status?: "DRAFTS" | "TODO" | "PAID" | "OVERDUE";
166+
bill_date_start?: string;
167+
bill_date_end?: string;
168+
due_date_start?: string;
169+
due_date_end?: string;
170+
vendor_ref?: string;
171+
title?: string;
172+
currency_code?: string;
173+
pending_amount_min?: number;
174+
pending_amount_max?: number;
175+
vendor?: string;
176+
gross_min?: number;
177+
gross_max?: number;
178+
net_min?: number;
179+
net_max?: number;
180+
document_no?: string;
181+
supplier_id?: number;
182+
average_exchange_rate_enabled?: boolean;
183+
}
184+
185+
export enum PaymentType {
186+
IBAN = "IBAN",
187+
MANUAL = "MANUAL",
188+
QR = "QR",
189+
}
190+
191+
export enum PaymentFee {
192+
BY_SENDER = "BY_SENDER",
193+
BY_RECEIVER = "BY_RECEIVER",
194+
BREAKDOWN = "BREAKDOWN",
195+
NO_FEE = "NO_FEE",
196+
}
197+
198+
export enum BillStatus {
199+
DRAFT = "DRAFT",
200+
BOOKED = "BOOKED",
201+
PARTIALLY_CREATED = "PARTIALLY_CREATED",
202+
CREATED = "CREATED",
203+
PARTIALLY_SENT = "PARTIALLY_SENT",
204+
SENT = "SENT",
205+
PARTIALLY_DOWNLOADED = "PARTIALLY_DOWNLOADED",
206+
DOWNLOADED = "DOWNLOADED",
207+
PARTIALLY_PAID = "PARTIALLY_PAID",
208+
PAID = "PAID",
209+
PARTIALLY_FAILED = "PARTIALLY_FAILED",
210+
FAILED = "FAILED",
211+
}
212+
}

src/resources/BillsV4.ts

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import { BillsV4Static } from "../interfaces/BillsV4Static";
2+
import BaseCrud from "./BaseCrud";
3+
import { BaseStatic } from "../interfaces/BaseStatic";
4+
5+
export default class BillsV4 extends BaseCrud<
6+
BillsV4Static.Bill,
7+
BillsV4Static.BillFull,
8+
BillsV4Static.Bill,
9+
BillsV4Static.SearchParameters,
10+
BillsV4Static.BillCreate,
11+
BillsV4Static.BillOverwrite
12+
> {
13+
constructor(apiToken: string) {
14+
super(apiToken, "/4.0/purchase/bills");
15+
}
16+
17+
/**
18+
* Lists the bills
19+
*
20+
* @param {BillsV4Static.ListOptions} [options]
21+
* @returns {Promise<BillsV4Static.Bill[]>}
22+
* @memberof BillsV4
23+
*/
24+
public async list(
25+
options?: BillsV4Static.ListOptions
26+
): Promise<BillsV4Static.Bill[]> {
27+
const response = await this.request<{ data: BillsV4Static.Bill[] }>(
28+
"GET",
29+
"/4.0/purchase/bills",
30+
options
31+
);
32+
return response.data;
33+
}
34+
35+
/**
36+
* Not implemented by Bexio yet
37+
*
38+
* @param {Array<BaseStatic.SearchParameter<BillsV4Static.SearchParameters>>} searchOptions
39+
* @param {BaseStatic.BaseOptions} [options]
40+
* @returns {Promise<BillsV4Static.Bill[]>}
41+
* @memberof BillsV4
42+
*/
43+
public async search(
44+
searchOptions: Array<
45+
BaseStatic.SearchParameter<BillsV4Static.SearchParameters>
46+
>,
47+
options?: BaseStatic.BaseOptions
48+
): Promise<BillsV4Static.Bill[]> {
49+
throw new Error("not implemented by Bexio yet");
50+
}
51+
52+
/**
53+
* Update bill status
54+
*
55+
* @param {string} id
56+
* @param {BillsV4Static.BillStatusUpdate} status
57+
* @returns {Promise<BillsV4Static.BillFull>}
58+
* @memberof BillsV4
59+
*/
60+
public async updateStatus(
61+
id: string,
62+
status: BillsV4Static.BillStatusUpdate
63+
): Promise<BillsV4Static.BillFull> {
64+
return this.request<BillsV4Static.BillFull>(
65+
"PUT",
66+
`${this.apiEndpoint}/${id}/bookings/${status}`
67+
);
68+
}
69+
70+
/**
71+
* Execute bill action
72+
*
73+
* @param {string} id
74+
* @param {BillsV4Static.BillAction} action
75+
* @returns {Promise<BillsV4Static.BillFull>}
76+
* @memberof BillsV4
77+
*/
78+
public async executeAction(
79+
id: string,
80+
action: BillsV4Static.BillAction
81+
): Promise<BillsV4Static.BillFull> {
82+
return this.request<BillsV4Static.BillFull>(
83+
"POST",
84+
`${this.apiEndpoint}/${id}/actions`,
85+
undefined,
86+
{ action }
87+
);
88+
}
89+
90+
/**
91+
* Validate whether document number is available or not
92+
*
93+
* @param {string} documentNo
94+
* @returns {Promise<{ valid: boolean; next_available_no: string }>}
95+
* @memberof BillsV4
96+
*/
97+
public async validateDocumentNumber(
98+
documentNo: string
99+
): Promise<{ valid: boolean; next_available_no: string }> {
100+
return this.request<{ valid: boolean; next_available_no: string }>(
101+
"GET",
102+
"/4.0/purchase/documentnumbers/bills",
103+
{ document_no: documentNo }
104+
);
105+
}
106+
}

0 commit comments

Comments
 (0)