Skip to content

Commit 753b271

Browse files
committed
feat: switch to lexoffice
1 parent e810376 commit 753b271

File tree

15 files changed

+654
-1611
lines changed

15 files changed

+654
-1611
lines changed

.github/workflows/deploy.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ jobs:
5858
echo "Running ${{ env.ENV }} mode (${{ github.ref }})"
5959
6060
echo "TOGGL_API_TOKEN=${{ secrets.TOGGL_API_TOKEN }}" >> ${GITHUB_ENV}
61-
echo "DEBITOOR_API_TOKEN=${{ secrets.DEBITOOR_API_TOKEN }}" >> ${GITHUB_ENV}
61+
echo "LEXOFFICE_API_TOKEN=${{ secrets.LEXOFFICE_API_TOKEN }}" >> ${GITHUB_ENV}
6262
echo "CONTENTFUL_ACCESS_TOKEN=${{ secrets.CONTENTFUL_ACCESS_TOKEN }}" >> ${GITHUB_ENV}
6363
echo "CONTENTFUL_SPACE_ID=${{ secrets.CONTENTFUL_SPACE_ID }}" >> ${GITHUB_ENV}
6464

serverless.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const serverlessConfiguration: AWS = {
3131
AWS_NODEJS_CONNECTION_REUSE_ENABLED: '1',
3232
STAGE: '${self:provider.stage}',
3333
TOGGL_API_TOKEN: '${env:TOGGL_API_TOKEN}',
34-
DEBITOOR_API_TOKEN: '${env:DEBITOOR_API_TOKEN}',
34+
LEXOFFICE_API_TOKEN: '${env:LEXOFFICE_API_TOKEN}',
3535
CONTENTFUL_SPACE_ID: '${env:CONTENTFUL_SPACE_ID}',
3636
CONTENTFUL_ACCESS_TOKEN: '${env:CONTENTFUL_ACCESS_TOKEN}',
3737
CONTENTFUL_ENVIRONMENT_ID: '${env:CONTENTFUL_ENVIRONMENT_ID, "master"}',

src/functions/debitoor/handler.ts

Lines changed: 0 additions & 149 deletions
This file was deleted.

src/functions/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
export { default as debitoor } from './debitoor';
1+
export { default as invoicing } from './invoicing';
22
export { default as sheet } from './sheet';
33
export { default as syncContentful } from './sync-contentful';

src/functions/invoicing/handler.ts

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import {
2+
httpResponse,
3+
ValidatedEventAPIGatewayProxyEvent,
4+
} from '@libs/apiGateway';
5+
import { LABEL_BILLED } from '@libs/constants';
6+
import { middyfy } from '@libs/lambda';
7+
import { createInvoices, isErrorResponse } from '@libs/lexoffice';
8+
import {
9+
bulkAddBilledTag,
10+
enrichTimeEntries,
11+
fetchTimeEntriesBetween,
12+
filterClientTimeEntriesByCustomer,
13+
filterTimeEntriesByLabel,
14+
sanitizeTimeEntries,
15+
} from '@libs/toggl';
16+
import { clearCaches, getConfig, Logger } from '@libs/utils';
17+
import 'source-map-support/register';
18+
import { ErrorResponse, Invoice } from '../../libs/lexoffice-types';
19+
import schema from '../schema';
20+
21+
const handler: ValidatedEventAPIGatewayProxyEvent<typeof schema> = async (
22+
event
23+
) => {
24+
try {
25+
const config = getConfig(event.body, (event as any).usePreviousMonth);
26+
const {
27+
dryRun,
28+
setBilled,
29+
labelWhitelist,
30+
labelBlacklist,
31+
customerWhitelist,
32+
customerBlacklist,
33+
time,
34+
} = config;
35+
36+
const timeEntries = await fetchTimeEntriesBetween(
37+
time.fromAsISO,
38+
time.toAsISO
39+
);
40+
41+
const billableTimeEntries = filterTimeEntriesByLabel(
42+
timeEntries,
43+
labelWhitelist,
44+
[...(labelBlacklist || []), LABEL_BILLED]
45+
);
46+
const sanitizedTimeEntries = sanitizeTimeEntries(billableTimeEntries);
47+
48+
let customerTimeEntries = await enrichTimeEntries(sanitizedTimeEntries);
49+
customerTimeEntries = filterClientTimeEntriesByCustomer(
50+
customerTimeEntries,
51+
customerWhitelist,
52+
customerBlacklist
53+
);
54+
55+
let invoices: Invoice[] = [];
56+
let erroneous: ErrorResponse[] = [];
57+
if (!dryRun) {
58+
const results = await createInvoices(customerTimeEntries, config);
59+
60+
erroneous = (results.filter(
61+
isErrorResponse
62+
) as unknown) as ErrorResponse[];
63+
invoices = (results.filter(
64+
(draftInvoice) => !isErrorResponse(draftInvoice)
65+
) as unknown) as Invoice[];
66+
67+
if (setBilled) {
68+
await bulkAddBilledTag(sanitizedTimeEntries);
69+
}
70+
}
71+
72+
delete config.time;
73+
74+
return httpResponse(
75+
200,
76+
`Created billing task with ${customerTimeEntries.length} subtask(s)`,
77+
{
78+
config,
79+
invoices: invoices,
80+
customerTimeEntries: dryRun ? customerTimeEntries : null,
81+
erroneous,
82+
}
83+
);
84+
} catch (error) {
85+
Logger.error(error);
86+
return httpResponse(error.statusCode, error.message, error);
87+
} finally {
88+
clearCaches();
89+
}
90+
};
91+
92+
export const main = middyfy(handler);

src/functions/debitoor/index.ts renamed to src/functions/invoicing/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export default {
88
{
99
http: {
1010
method: 'post',
11-
path: 'debitoor',
11+
path: 'invoicing',
1212
request: {
1313
schemas: {
1414
'application/json': schema,
File renamed without changes.

src/functions/sync-contentful/handler.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,22 @@ import {
22
httpResponse,
33
ValidatedEventAPIGatewayProxyEvent,
44
} from '@libs/apiGateway';
5-
import {
6-
updateDebitoorCustomers,
7-
updateDebitoorProducts,
8-
} from '@libs/debitoor';
95
import { middyfy } from '@libs/lambda';
10-
import { updateTogglClients, updateTogglProjects } from '@libs/toggl';
6+
import * as lexoffice from '@libs/lexoffice';
7+
import * as toggl from '@libs/toggl';
118
import { clearCaches, Logger } from '@libs/utils';
129
import 'source-map-support/register';
1310

1411
const handler: ValidatedEventAPIGatewayProxyEvent<unknown> = async () => {
1512
try {
16-
await updateDebitoorProducts();
17-
await updateDebitoorCustomers();
18-
await updateTogglClients();
19-
await updateTogglProjects();
13+
await lexoffice.updateCustomers();
14+
await toggl.updateClients();
15+
await toggl.updateProjects();
2016

21-
return httpResponse(200, `Updated debitoor and toggl with contentful data`);
17+
return httpResponse(
18+
200,
19+
`Updated lexoffice and toggl with contentful data`
20+
);
2221
} catch (error) {
2322
Logger.error(error);
2423
return httpResponse(error.statusCode, error.message, error);

0 commit comments

Comments
 (0)