@moatless/bookkeeping 0.3.0 → 0.4.0
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/services/document-download.d.ts +1 -7
- package/dist/services/document-download.js +3 -1
- package/dist/services/index.d.ts +1 -1
- package/dist/services/journal.service.js +21 -5
- package/dist/skills/cli-usage.d.ts +2 -0
- package/dist/skills/cli-usage.js +283 -0
- package/dist/skills/index.d.ts +1 -0
- package/dist/skills/index.js +1 -0
- package/dist/types/document.d.ts +5 -2
- package/dist/types/journal-entry.d.ts +2 -1
- package/dist/utils/git.d.ts +5 -0
- package/dist/utils/git.js +18 -0
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/yaml/entry-helpers.d.ts +1 -8
- package/package.json +2 -2
|
@@ -1,10 +1,4 @@
|
|
|
1
1
|
import type { IStorageService } from "../storage/interface";
|
|
2
|
-
export interface DocumentMetadata {
|
|
3
|
-
fileName: string;
|
|
4
|
-
mimeType?: string;
|
|
5
|
-
sourceIntegration: string;
|
|
6
|
-
sourceId: string;
|
|
7
|
-
}
|
|
8
2
|
export interface DownloadableFile {
|
|
9
3
|
id: string;
|
|
10
4
|
contentType: string;
|
|
@@ -33,7 +27,7 @@ export interface DownloadFilesOptions {
|
|
|
33
27
|
entryDir: string;
|
|
34
28
|
journalEntryId: string;
|
|
35
29
|
downloader: FileDownloader;
|
|
36
|
-
sourceIntegration:
|
|
30
|
+
sourceIntegration: "fortnox" | "bokio";
|
|
37
31
|
}
|
|
38
32
|
/**
|
|
39
33
|
* Download files for a journal entry and save them to documents.yaml
|
|
@@ -77,8 +77,10 @@ export async function downloadFilesForEntry(options) {
|
|
|
77
77
|
const filePath = path.join(absoluteDir, filename);
|
|
78
78
|
const buffer = Buffer.from(result.data);
|
|
79
79
|
await fs.writeFile(filePath, buffer);
|
|
80
|
-
// Add to documents list
|
|
80
|
+
// Add to documents list (downloaded docs are already POSTED in provider)
|
|
81
81
|
existingDocs.push({
|
|
82
|
+
kind: "FILE",
|
|
83
|
+
status: "POSTED",
|
|
82
84
|
fileName: filename,
|
|
83
85
|
mimeType: file.contentType || result.contentType,
|
|
84
86
|
sourceIntegration,
|
package/dist/services/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { JournalService } from "./journal.service";
|
|
2
2
|
export { syncJournalEntries, type SyncJournalConfig, } from "./journal-sync";
|
|
3
|
-
export { downloadFilesForEntry, getExtensionFromMimeType, type
|
|
3
|
+
export { downloadFilesForEntry, getExtensionFromMimeType, type DownloadableFile, type FileDownloader, type DownloadFilesOptions, } from "./document-download";
|
|
4
4
|
export { syncFortnoxJournalEntries, syncFortnoxChartOfAccounts, type FortnoxSyncProgress, type FortnoxJournalSyncOptions, type FortnoxJournalSyncResult, } from "./fortnox-journal";
|
|
5
5
|
export { syncFortnoxInbox, type FortnoxInboxSyncProgress, type FortnoxInboxSyncOptions, type FortnoxInboxSyncResult, } from "./fortnox-inbox";
|
|
6
6
|
export { syncBokioJournalEntries, syncBokioChartOfAccounts, type BokioSyncProgress, type BokioJournalSyncOptions, type BokioJournalSyncResult, } from "./bokio-journal";
|
|
@@ -9,9 +9,18 @@ export class JournalService {
|
|
|
9
9
|
constructor(storage) {
|
|
10
10
|
this.storage = storage;
|
|
11
11
|
}
|
|
12
|
-
static getEntryKey(entry) {
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
static getEntryKey(entry, entryDir) {
|
|
13
|
+
// If entry has externalId, use it (synced entries)
|
|
14
|
+
if (entry.externalId) {
|
|
15
|
+
return entry.externalId;
|
|
16
|
+
}
|
|
17
|
+
// For local entries without externalId, use directory path if available
|
|
18
|
+
// This prevents collisions when multiple entries have same entry number
|
|
19
|
+
if (entryDir) {
|
|
20
|
+
return entryDir;
|
|
21
|
+
}
|
|
22
|
+
// Fallback for backward compatibility
|
|
23
|
+
return `${entry.series ?? ""}-${entry.entryNumber}`;
|
|
15
24
|
}
|
|
16
25
|
/**
|
|
17
26
|
* List all journal entries from a fiscal year
|
|
@@ -41,7 +50,7 @@ export class JournalService {
|
|
|
41
50
|
try {
|
|
42
51
|
const { content } = await this.storage.readFile(entryPath);
|
|
43
52
|
const journalEntry = parseYaml(content);
|
|
44
|
-
const key = JournalService.getEntryKey(journalEntry);
|
|
53
|
+
const key = JournalService.getEntryKey(journalEntry, dir.path);
|
|
45
54
|
entriesMap.set(key, {
|
|
46
55
|
entry: journalEntry,
|
|
47
56
|
entryPath,
|
|
@@ -49,7 +58,14 @@ export class JournalService {
|
|
|
49
58
|
});
|
|
50
59
|
}
|
|
51
60
|
catch (error) {
|
|
52
|
-
|
|
61
|
+
// Warn about missing/invalid entry.yaml but continue processing other entries
|
|
62
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
63
|
+
if (message.includes("ENOENT")) {
|
|
64
|
+
console.warn(` Warning: Skipping ${dir.path} - missing entry.yaml`);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
console.warn(` Warning: Skipping ${dir.path} - ${message}`);
|
|
68
|
+
}
|
|
53
69
|
}
|
|
54
70
|
}
|
|
55
71
|
}
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
export const CLI_USAGE_SKILL = {
|
|
2
|
+
name: "cli-usage",
|
|
3
|
+
description: "Quick start guide for ledgit CLI - essential commands and workflow. Use when learning ledgit basics, creating entries, syncing data from accounting providers (Fortnox/Bokio), or managing inbox items. Triggers on tasks involving ledgit setup, repository structure, command usage, or git-based bookkeeping workflow.",
|
|
4
|
+
content: `# Ledgit CLI - Quick Start Guide
|
|
5
|
+
|
|
6
|
+
Get started with ledgit, a git-based bookkeeping system for Swedish companies integrating with Fortnox or Bokio.
|
|
7
|
+
|
|
8
|
+
## What is Ledgit?
|
|
9
|
+
|
|
10
|
+
Ledgit stores accounting data as YAML files in a git repository, providing:
|
|
11
|
+
- Version control for all financial records
|
|
12
|
+
- Human-readable accounting entries
|
|
13
|
+
- Seamless integration with Swedish accounting providers
|
|
14
|
+
- Git workflow for review and approval
|
|
15
|
+
|
|
16
|
+
## Repository Structure
|
|
17
|
+
|
|
18
|
+
\`\`\`
|
|
19
|
+
/
|
|
20
|
+
├── accounts.yaml # Swedish chart of accounts (BAS codes 1000-9999)
|
|
21
|
+
├── journal-entries/ # Main accounting data organized by fiscal year
|
|
22
|
+
│ └── FY-YYYY/ # Fiscal year folders (FY-2024, FY-2025, etc.)
|
|
23
|
+
│ ├── _fiscal-year.yaml
|
|
24
|
+
│ └── [SERIES]-[NUM]-[DATE]-[DESC]/
|
|
25
|
+
│ ├── entry.yaml # Journal entry data
|
|
26
|
+
│ └── *.pdf # Supporting documents
|
|
27
|
+
│
|
|
28
|
+
└── inbox/ # Raw incoming documents (no entry yet)
|
|
29
|
+
└── [DATE]-[NAME]/
|
|
30
|
+
├── documents.yaml # Document metadata
|
|
31
|
+
└── *.pdf # Files to process
|
|
32
|
+
\`\`\`
|
|
33
|
+
|
|
34
|
+
## Common Workflow
|
|
35
|
+
|
|
36
|
+
The typical bookkeeping workflow:
|
|
37
|
+
|
|
38
|
+
\`\`\`
|
|
39
|
+
inbox/ → (create-entry) → journal-entries/ → (git review) → (sync-journal) → Provider
|
|
40
|
+
\`\`\`
|
|
41
|
+
|
|
42
|
+
**Steps:**
|
|
43
|
+
1. Run \`ledgit sync-inbox\` to download new documents from provider
|
|
44
|
+
2. Review inbox item (read PDF, check \`documents.yaml\`)
|
|
45
|
+
3. Run \`ledgit create-entry\` with appropriate flags
|
|
46
|
+
4. Review changes with \`git diff\`, commit if correct
|
|
47
|
+
5. Run \`ledgit sync-journal\` to post entry back to provider
|
|
48
|
+
|
|
49
|
+
**Branching:** When running \`create-entry\` on main branch, a new git branch is automatically created (e.g., \`book/V-189-2025-10-15-anthropic\`). Review, commit, and merge when ready.
|
|
50
|
+
|
|
51
|
+
## Essential Commands
|
|
52
|
+
|
|
53
|
+
### Syncing Data
|
|
54
|
+
|
|
55
|
+
\`\`\`bash
|
|
56
|
+
# Download new inbox documents from provider
|
|
57
|
+
ledgit sync-inbox
|
|
58
|
+
|
|
59
|
+
# Sync journal entries from provider to local repo
|
|
60
|
+
ledgit sync-journal
|
|
61
|
+
|
|
62
|
+
# Display company information
|
|
63
|
+
ledgit company-info
|
|
64
|
+
\`\`\`
|
|
65
|
+
|
|
66
|
+
### Creating Entries
|
|
67
|
+
|
|
68
|
+
\`\`\`bash
|
|
69
|
+
# Create entry from inbox directory
|
|
70
|
+
ledgit create-entry --path <inbox-dir> \\
|
|
71
|
+
--tax-code <code> \\
|
|
72
|
+
--base-account <account> \\
|
|
73
|
+
--balancing-account <account> \\
|
|
74
|
+
--series <A-K>
|
|
75
|
+
|
|
76
|
+
# Example: Create entry for AWS invoice
|
|
77
|
+
ledgit create-entry --path inbox/2025-01-15-aws \\
|
|
78
|
+
--tax-code SE_VAT_25_PURCHASE_NON_EU_SERVICES_RC \\
|
|
79
|
+
--base-account 5422 \\
|
|
80
|
+
--balancing-account 2820 \\
|
|
81
|
+
--series D
|
|
82
|
+
\`\`\`
|
|
83
|
+
|
|
84
|
+
**Common flags:**
|
|
85
|
+
- \`--path\` - Path to inbox directory or raw file
|
|
86
|
+
- \`--tax-code\` - Swedish VAT code (see \`ledgit list-tax-codes\`)
|
|
87
|
+
- \`--base-account\` - Expense/revenue account (from \`accounts.yaml\`)
|
|
88
|
+
- \`--balancing-account\` - 2440 (payable), 2820 (credit card), or 1930 (bank)
|
|
89
|
+
- \`--series\` - A=Admin, D=Supplier invoices, E=Supplier payments, etc.
|
|
90
|
+
|
|
91
|
+
**For raw files** (not from inbox):
|
|
92
|
+
- \`--description "Vendor name"\`
|
|
93
|
+
- \`--document-date 2025-01-15\`
|
|
94
|
+
- \`--amount 1234.50\`
|
|
95
|
+
|
|
96
|
+
### Currency Conversion
|
|
97
|
+
|
|
98
|
+
\`\`\`bash
|
|
99
|
+
# Convert foreign currency to SEK (automatic Riksbank rates)
|
|
100
|
+
ledgit convert-currency --amount 100 --currency USD --date 2025-01-15
|
|
101
|
+
|
|
102
|
+
# When creating entries with foreign currency
|
|
103
|
+
ledgit create-entry --path inbox/2025-01-15-stripe \\
|
|
104
|
+
--currency USD \\
|
|
105
|
+
--tax-code SE_VAT_25_PURCHASE_NON_EU_SERVICES_RC \\
|
|
106
|
+
--base-account 5422 \\
|
|
107
|
+
--balancing-account 2820 \\
|
|
108
|
+
--series D
|
|
109
|
+
\`\`\`
|
|
110
|
+
|
|
111
|
+
Amounts are automatically converted to SEK using Riksbank exchange rates for the entry date. Rates are cached locally for efficiency.
|
|
112
|
+
|
|
113
|
+
### Managing Inbox
|
|
114
|
+
|
|
115
|
+
\`\`\`bash
|
|
116
|
+
# Discard unwanted inbox item (marks for deletion from provider)
|
|
117
|
+
ledgit discard inbox/2025-01-15-spam-document
|
|
118
|
+
\`\`\`
|
|
119
|
+
|
|
120
|
+
### Reference Information
|
|
121
|
+
|
|
122
|
+
\`\`\`bash
|
|
123
|
+
# List all available Swedish tax codes
|
|
124
|
+
ledgit list-tax-codes
|
|
125
|
+
\`\`\`
|
|
126
|
+
|
|
127
|
+
## Creating Your First Entry
|
|
128
|
+
|
|
129
|
+
Step-by-step walkthrough:
|
|
130
|
+
|
|
131
|
+
### 1. Sync Inbox
|
|
132
|
+
\`\`\`bash
|
|
133
|
+
ledgit sync-inbox
|
|
134
|
+
\`\`\`
|
|
135
|
+
This downloads new documents to \`inbox/\` directories.
|
|
136
|
+
|
|
137
|
+
### 2. Review Document
|
|
138
|
+
Read the PDF or check \`documents.yaml\` for metadata:
|
|
139
|
+
\`\`\`yaml
|
|
140
|
+
- fileName: invoice.pdf
|
|
141
|
+
description: Vendor Name
|
|
142
|
+
documentDate: 2025-01-15
|
|
143
|
+
totalAmount:
|
|
144
|
+
amount: "1250.00"
|
|
145
|
+
currency: SEK
|
|
146
|
+
\`\`\`
|
|
147
|
+
|
|
148
|
+
### 3. Look for Similar Entries
|
|
149
|
+
Search \`journal-entries/\` for entries from the same vendor to learn which accounts and tax codes were used previously.
|
|
150
|
+
|
|
151
|
+
### 4. Check Accounts
|
|
152
|
+
Review \`accounts.yaml\` for appropriate expense/revenue accounts. Common examples:
|
|
153
|
+
- 5422 - SaaS/Software
|
|
154
|
+
- 6540 - IT services
|
|
155
|
+
- 6530 - Accounting services
|
|
156
|
+
- 5800 - Travel expenses
|
|
157
|
+
|
|
158
|
+
### 5. Determine Tax Code
|
|
159
|
+
Based on vendor location and transaction type. **For detailed tax code guidance, run:**
|
|
160
|
+
\`\`\`bash
|
|
161
|
+
ledgit skills swedish-bookkeeping
|
|
162
|
+
\`\`\`
|
|
163
|
+
|
|
164
|
+
Quick reference:
|
|
165
|
+
- Swedish supplier with VAT → \`SE_VAT_25_PURCHASE_DOMESTIC\`
|
|
166
|
+
- EU services → \`SE_VAT_25_PURCHASE_EU_SERVICES_RC\`
|
|
167
|
+
- Non-EU (US/UK) services → \`SE_VAT_25_PURCHASE_NON_EU_SERVICES_RC\`
|
|
168
|
+
|
|
169
|
+
### 6. Create Entry
|
|
170
|
+
\`\`\`bash
|
|
171
|
+
ledgit create-entry --path inbox/2025-01-15-vendor \\
|
|
172
|
+
--tax-code SE_VAT_25_PURCHASE_NON_EU_SERVICES_RC \\
|
|
173
|
+
--base-account 5422 \\
|
|
174
|
+
--balancing-account 2820 \\
|
|
175
|
+
--series D
|
|
176
|
+
\`\`\`
|
|
177
|
+
|
|
178
|
+
### 7. Review and Sync
|
|
179
|
+
\`\`\`bash
|
|
180
|
+
# Review changes
|
|
181
|
+
git diff
|
|
182
|
+
|
|
183
|
+
# Commit if correct
|
|
184
|
+
git add .
|
|
185
|
+
git commit -m "Add: Vendor Name invoice"
|
|
186
|
+
|
|
187
|
+
# Post to provider
|
|
188
|
+
ledgit sync-journal
|
|
189
|
+
\`\`\`
|
|
190
|
+
|
|
191
|
+
## Skills System
|
|
192
|
+
|
|
193
|
+
Ledgit includes domain-specific skills with detailed guidance. **Always load the relevant skill before creating unfamiliar entries.**
|
|
194
|
+
|
|
195
|
+
\`\`\`bash
|
|
196
|
+
# List all available skills
|
|
197
|
+
ledgit skills
|
|
198
|
+
|
|
199
|
+
# Load specific skill
|
|
200
|
+
ledgit skills swedish-bookkeeping # VAT, tax codes, BAS accounts
|
|
201
|
+
ledgit skills travel-expenses # Hotels, flights, per diem
|
|
202
|
+
\`\`\`
|
|
203
|
+
|
|
204
|
+
**When to use skills:**
|
|
205
|
+
- \`swedish-bookkeeping\` - Creating any journal entry, handling VAT/moms, selecting accounts
|
|
206
|
+
- \`travel-expenses\` - Business travel, hotels, flights, traktamente (per diem), mileage
|
|
207
|
+
|
|
208
|
+
## Entry File Format
|
|
209
|
+
|
|
210
|
+
Basic \`entry.yaml\` structure:
|
|
211
|
+
|
|
212
|
+
\`\`\`yaml
|
|
213
|
+
series: D # A=Admin, B=Customer invoices, C=Customer payments,
|
|
214
|
+
# D=Supplier invoices, E=Supplier payments, K=Salary
|
|
215
|
+
entryNumber: 189
|
|
216
|
+
entryDate: 2025-01-15
|
|
217
|
+
description: Vendor Name - Service description
|
|
218
|
+
status: POSTED # or DRAFT
|
|
219
|
+
currency: SEK
|
|
220
|
+
lines:
|
|
221
|
+
- account: "5422" # Expense account (from accounts.yaml)
|
|
222
|
+
debit: 1000.00
|
|
223
|
+
memo: SaaS subscription
|
|
224
|
+
- account: "2645" # Input VAT (if reverse charge)
|
|
225
|
+
debit: 250.00
|
|
226
|
+
memo: Input VAT reverse charge
|
|
227
|
+
- account: "2614" # Output VAT (if reverse charge)
|
|
228
|
+
credit: 250.00
|
|
229
|
+
memo: Output VAT reverse charge
|
|
230
|
+
- account: "2820" # Balancing account
|
|
231
|
+
credit: 1000.00
|
|
232
|
+
memo: Credit card payment
|
|
233
|
+
\`\`\`
|
|
234
|
+
|
|
235
|
+
**Entry must balance:** Total debits must equal total credits.
|
|
236
|
+
|
|
237
|
+
## Series Codes
|
|
238
|
+
|
|
239
|
+
| Series | Swedish | Use |
|
|
240
|
+
|--------|---------|-----|
|
|
241
|
+
| A | Administration | Internal adjustments, corrections |
|
|
242
|
+
| B | Kundfakturor | Customer invoices (sales) |
|
|
243
|
+
| C | Kundbetalningar | Customer payments received |
|
|
244
|
+
| D | Leverantörsfakturor | Supplier invoices (purchases) |
|
|
245
|
+
| E | Leverantörsbetalningar | Supplier payments made |
|
|
246
|
+
| K | Löner | Salary and payroll |
|
|
247
|
+
|
|
248
|
+
Most common: **D** (supplier invoices) and **E** (supplier payments).
|
|
249
|
+
|
|
250
|
+
## Account Codes Quick Reference
|
|
251
|
+
|
|
252
|
+
Swedish BAS account ranges:
|
|
253
|
+
- **1xxx** - Assets (bank accounts, receivables)
|
|
254
|
+
- **2xxx** - Liabilities (payables, VAT, credit cards)
|
|
255
|
+
- **3xxx** - Revenue
|
|
256
|
+
- **4xxx** - Cost of Goods Sold
|
|
257
|
+
- **5-6xxx** - Operating Expenses
|
|
258
|
+
- **7xxx** - Personnel costs
|
|
259
|
+
- **8xxx** - Financial items
|
|
260
|
+
|
|
261
|
+
See \`accounts.yaml\` in your repository for the company's full chart of accounts.
|
|
262
|
+
|
|
263
|
+
## Common Balancing Accounts
|
|
264
|
+
|
|
265
|
+
| Account | Name | Use |
|
|
266
|
+
|---------|------|-----|
|
|
267
|
+
| 1930 | Business checking account | Direct debit/immediate payment |
|
|
268
|
+
| 2440 | Supplier payable | When paying later via bank transfer |
|
|
269
|
+
| 2820 | Credit card | Direct credit card charge |
|
|
270
|
+
|
|
271
|
+
## Next Steps
|
|
272
|
+
|
|
273
|
+
1. Run \`ledgit company-info\` to verify your setup
|
|
274
|
+
2. Run \`ledgit sync-inbox\` to get documents
|
|
275
|
+
3. Run \`ledgit skills swedish-bookkeeping\` for detailed tax code guidance
|
|
276
|
+
4. Create your first entry following the workflow above
|
|
277
|
+
5. Review with \`git diff\` and commit when ready
|
|
278
|
+
|
|
279
|
+
**Questions?** Load the appropriate skill for detailed guidance:
|
|
280
|
+
- General bookkeeping → \`ledgit skills swedish-bookkeeping\`
|
|
281
|
+
- Travel expenses → \`ledgit skills travel-expenses\`
|
|
282
|
+
`,
|
|
283
|
+
};
|
package/dist/skills/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export type { Skill } from "./types";
|
|
2
2
|
export { SWEDISH_BOOKKEEPING_SKILL } from "./swedish-bookkeeping";
|
|
3
3
|
export { TRAVEL_EXPENSES_SKILL } from "./travel-expenses";
|
|
4
|
+
export { CLI_USAGE_SKILL } from "./cli-usage";
|
|
4
5
|
import type { Skill } from "./types";
|
|
5
6
|
export declare const SKILLS: Skill[];
|
|
6
7
|
export declare function listSkills(): Skill[];
|
package/dist/skills/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { SWEDISH_BOOKKEEPING_SKILL } from "./swedish-bookkeeping";
|
|
2
2
|
export { TRAVEL_EXPENSES_SKILL } from "./travel-expenses";
|
|
3
|
+
export { CLI_USAGE_SKILL } from "./cli-usage";
|
|
3
4
|
import { SWEDISH_BOOKKEEPING_SKILL } from "./swedish-bookkeeping";
|
|
4
5
|
import { TRAVEL_EXPENSES_SKILL } from "./travel-expenses";
|
|
5
6
|
export const SKILLS = [
|
package/dist/types/document.d.ts
CHANGED
|
@@ -25,11 +25,11 @@ export interface TaxDetail {
|
|
|
25
25
|
/**
|
|
26
26
|
* Document kind/type
|
|
27
27
|
*/
|
|
28
|
-
export type DocumentKind = "RECEIPT" | "SUPPLIER_INVOICE" | "CUSTOMER_INVOICE" | "TRAKTAMENTE" | "OTHER";
|
|
28
|
+
export type DocumentKind = "RECEIPT" | "SUPPLIER_INVOICE" | "CUSTOMER_INVOICE" | "TRAKTAMENTE" | "FILE" | "OTHER";
|
|
29
29
|
/**
|
|
30
30
|
* Document status in workflow
|
|
31
31
|
*/
|
|
32
|
-
export type DocumentStatus = "DRAFT" | "REVIEWED" | "READY_TO_EXPORT" | "EXPORTED" | "ERROR" | "DISCARDED" | "POSTED";
|
|
32
|
+
export type DocumentStatus = "DRAFT" | "REVIEWED" | "READY_TO_EXPORT" | "EXPORTED" | "ERROR" | "DISCARDED" | "POSTED" | "PENDING_CONNECTION";
|
|
33
33
|
/**
|
|
34
34
|
* Complete exported document with parsed data
|
|
35
35
|
*
|
|
@@ -60,4 +60,7 @@ export interface Document {
|
|
|
60
60
|
sourceId?: string;
|
|
61
61
|
uploadedAt?: string;
|
|
62
62
|
interpretedAt?: string;
|
|
63
|
+
errorMessage?: string;
|
|
64
|
+
linkedToJournalEntry?: boolean;
|
|
65
|
+
previousSourceIds?: string[];
|
|
63
66
|
}
|
|
@@ -66,7 +66,6 @@ export interface JournalEntry {
|
|
|
66
66
|
lines: JournalLine[];
|
|
67
67
|
postedAt?: string;
|
|
68
68
|
errorMessage?: string;
|
|
69
|
-
postingCheckpoint?: string;
|
|
70
69
|
voucherNumber?: number;
|
|
71
70
|
voucherSeriesCode?: string;
|
|
72
71
|
fortnoxFileId?: string;
|
|
@@ -76,4 +75,6 @@ export interface JournalEntry {
|
|
|
76
75
|
reversingEntryExternalId?: string;
|
|
77
76
|
/** If this entry was reversed/cancelled, the external ID of the reversing entry */
|
|
78
77
|
reversedByEntryExternalId?: string;
|
|
78
|
+
/** The external ID of the fiscal year this entry belongs to (e.g., Fortnox year ID) */
|
|
79
|
+
fiscalYearExternalId?: number;
|
|
79
80
|
}
|
package/dist/utils/git.d.ts
CHANGED
|
@@ -2,8 +2,13 @@
|
|
|
2
2
|
* Initialize a new git repository with a .gitignore file
|
|
3
3
|
*/
|
|
4
4
|
export declare function initGitRepo(repoPath: string): Promise<void>;
|
|
5
|
+
/**
|
|
6
|
+
* Check if a directory is a git repository
|
|
7
|
+
*/
|
|
8
|
+
export declare function isGitRepo(repoPath: string): Promise<boolean>;
|
|
5
9
|
/**
|
|
6
10
|
* Stage all changes and commit with the given message.
|
|
7
11
|
* Returns true if a commit was made, false if there were no changes to commit.
|
|
12
|
+
* Returns false if the directory is not a git repository.
|
|
8
13
|
*/
|
|
9
14
|
export declare function commitAll(repoPath: string, message: string): Promise<boolean>;
|
package/dist/utils/git.js
CHANGED
|
@@ -26,11 +26,29 @@ export async function initGitRepo(repoPath) {
|
|
|
26
26
|
await git.init();
|
|
27
27
|
await fs.writeFile(path.join(repoPath, ".gitignore"), DEFAULT_GITIGNORE);
|
|
28
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Check if a directory is a git repository
|
|
31
|
+
*/
|
|
32
|
+
export async function isGitRepo(repoPath) {
|
|
33
|
+
try {
|
|
34
|
+
const git = simpleGit(repoPath);
|
|
35
|
+
await git.revparse(["--git-dir"]);
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
29
42
|
/**
|
|
30
43
|
* Stage all changes and commit with the given message.
|
|
31
44
|
* Returns true if a commit was made, false if there were no changes to commit.
|
|
45
|
+
* Returns false if the directory is not a git repository.
|
|
32
46
|
*/
|
|
33
47
|
export async function commitAll(repoPath, message) {
|
|
48
|
+
// Check if it's a git repository first
|
|
49
|
+
if (!(await isGitRepo(repoPath))) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
34
52
|
const git = simpleGit(repoPath);
|
|
35
53
|
await git.add(".");
|
|
36
54
|
const status = await git.status();
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { journalEntryDirName, journalEntryPath, journalEntryDirFromPath, fiscalYearDirName, sanitizeOrgName, } from "./file-namer";
|
|
2
2
|
export { parseYaml, toYaml } from "./yaml";
|
|
3
3
|
export { withRetry, isRateLimitError, type RetryOptions } from "./retry";
|
|
4
|
-
export { initGitRepo, commitAll } from "./git";
|
|
4
|
+
export { initGitRepo, commitAll, isGitRepo } from "./git";
|
|
5
5
|
export { getAgentsTemplate, renderAgentsTemplate, type RenderAgentsTemplateOptions, } from "./templates";
|
|
6
6
|
export { LEDGIT_DIR, getLedgitDir, getTokensDir, getCacheDir, } from "./paths";
|
package/dist/utils/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { journalEntryDirName, journalEntryPath, journalEntryDirFromPath, fiscalYearDirName, sanitizeOrgName, } from "./file-namer";
|
|
2
2
|
export { parseYaml, toYaml } from "./yaml";
|
|
3
3
|
export { withRetry, isRateLimitError } from "./retry";
|
|
4
|
-
export { initGitRepo, commitAll } from "./git";
|
|
4
|
+
export { initGitRepo, commitAll, isGitRepo } from "./git";
|
|
5
5
|
export { getAgentsTemplate, renderAgentsTemplate, } from "./templates";
|
|
6
6
|
export { LEDGIT_DIR, getLedgitDir, getTokensDir, getCacheDir, } from "./paths";
|
|
@@ -8,16 +8,10 @@ import type { JournalLineInput } from "../accounting";
|
|
|
8
8
|
* Read and parse entry.yaml file
|
|
9
9
|
*/
|
|
10
10
|
export declare function readEntryYaml(filePath: string): Promise<JournalEntry>;
|
|
11
|
-
interface DocumentMetadata {
|
|
12
|
-
fileName: string;
|
|
13
|
-
mimeType?: string;
|
|
14
|
-
sourceIntegration?: string;
|
|
15
|
-
sourceId?: string;
|
|
16
|
-
}
|
|
17
11
|
/**
|
|
18
12
|
* Read and parse documents.yaml file (list format)
|
|
19
13
|
*/
|
|
20
|
-
export declare function readDocumentsYaml(filePath: string): Promise<
|
|
14
|
+
export declare function readDocumentsYaml(filePath: string): Promise<Document[]>;
|
|
21
15
|
/**
|
|
22
16
|
* @deprecated Use readDocumentsYaml instead
|
|
23
17
|
* Read and parse document.yaml file (legacy single object format)
|
|
@@ -54,4 +48,3 @@ export declare function getAccountName(accountCode: string, accounts: Array<{
|
|
|
54
48
|
code: string;
|
|
55
49
|
name: string;
|
|
56
50
|
}>): string | undefined;
|
|
57
|
-
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moatless/bookkeeping",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@moatless/api-client": "^0.1.2",
|
|
26
|
-
"@moatless/bookkeeping-types": "^0.
|
|
26
|
+
"@moatless/bookkeeping-types": "^0.3.0",
|
|
27
27
|
"@moatless/fortnox-client": "^0.1.2",
|
|
28
28
|
"@moatless/bokio-client": "^0.1.2",
|
|
29
29
|
"cli-progress": "^3.12.0",
|