@kevludwig/lexware-office 0.1.2 → 0.1.4

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.d.ts CHANGED
@@ -2,7 +2,7 @@ export { DEFAULT_APP_URL, DEFAULT_BASE_URL, LexwareApiError, createLexwareClient
2
2
  export { contactEmail, createCustomer, findContactByNumber, findContactsByName, MIN_NAME_SEARCH_LENGTH, getContact, resolveContactByName, type Contact, type CreatedCustomer, type NewCustomer, } from "./contacts.ts";
3
3
  export { addDays, berlinDay, daysSince } from "./dates.ts";
4
4
  export { downloadInvoicePdf, findOverdueInvoice, findOverdueInvoices, type OverdueInvoice, } from "./receivables.ts";
5
- export { DEFAULT_REMINDER_POLICY, daysPastReminderDue, earliestReminderDate, isDueImmediately, isOpenForReminder, reminderDueDate, reminderLedger, selectDueReminders, type DueReminder, type ReminderHold, type ReminderLedger, type ReminderPolicy, type ReminderRecord, type ReminderSelection, type ReminderStatus, sendReminder, type ReminderTarget, type SendReminderOutcome, } from "./reminders.ts";
5
+ export { DEFAULT_REMINDER_POLICY, daysPastReminderDue, earliestReminderDate, isDueImmediately, isOpenForReminder, reminderDueDate, reminderLedger, selectDueReminders, type DueReminder, type ReminderHold, type ReminderLedger, type ReminderPolicy, type ReminderRecord, type ReminderSelection, type ReminderStatus, mailContentSha256, paymentReminderEffect, sendReminder, type PaymentReminderEffect, type ReminderTarget, type SendReminderOutcome, } from "./reminders.ts";
6
6
  export { MailNotSentError, defaultReminderMail, reminderSubject, type ReminderMail, type ReminderMailData, type ReminderSender, type RenderReminderMail, type SendReminderMail, } from "./reminder-mail.ts";
7
7
  export { keySegment, memoryStore, type JsonStore } from "./store.ts";
8
8
  export { DUPLICATE_TOTAL_TOLERANCE, ITEMS_TOTAL_TOLERANCE, netTotal, round2, taxFromGross, taxFromNet, type PricedLine, } from "./money.ts";
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ export { DEFAULT_APP_URL, DEFAULT_BASE_URL, LexwareApiError, createLexwareClient
2
2
  export { contactEmail, createCustomer, findContactByNumber, findContactsByName, MIN_NAME_SEARCH_LENGTH, getContact, resolveContactByName, } from "./contacts.js";
3
3
  export { addDays, berlinDay, daysSince } from "./dates.js";
4
4
  export { downloadInvoicePdf, findOverdueInvoice, findOverdueInvoices, } from "./receivables.js";
5
- export { DEFAULT_REMINDER_POLICY, daysPastReminderDue, earliestReminderDate, isDueImmediately, isOpenForReminder, reminderDueDate, reminderLedger, selectDueReminders, sendReminder, } from "./reminders.js";
5
+ export { DEFAULT_REMINDER_POLICY, daysPastReminderDue, earliestReminderDate, isDueImmediately, isOpenForReminder, reminderDueDate, reminderLedger, selectDueReminders, mailContentSha256, paymentReminderEffect, sendReminder, } from "./reminders.js";
6
6
  export { MailNotSentError, defaultReminderMail, reminderSubject, } from "./reminder-mail.js";
7
7
  export { keySegment, memoryStore } from "./store.js";
8
8
  export { DUPLICATE_TOTAL_TOLERANCE, ITEMS_TOTAL_TOLERANCE, netTotal, round2, taxFromGross, taxFromNet, } from "./money.js";
@@ -15,7 +15,7 @@
15
15
  */
16
16
  import type { LexwareClient } from "./client.ts";
17
17
  import { type OverdueInvoice } from "./receivables.ts";
18
- import { type RenderReminderMail, type SendReminderMail } from "./reminder-mail.ts";
18
+ import { type RenderReminderMail, type ReminderMail, type SendReminderMail } from "./reminder-mail.ts";
19
19
  import { type JsonStore } from "./store.ts";
20
20
  export interface ReminderPolicy {
21
21
  /** Days past the reminder due date before a first reminder. Default: 3. */
@@ -134,10 +134,40 @@ export type SendReminderOutcome = {
134
134
  sent: true;
135
135
  openAmount: number;
136
136
  attachment: string;
137
+ /** sha256 of subject, text and HTML as sent: proves what went out without keeping the mail. */
138
+ contentSha256: string;
137
139
  } | {
138
140
  sent: false;
139
141
  reason: "paid" | "taken";
140
142
  };
143
+ /**
144
+ * What a sent payment reminder did, in a fixed shape an app's protocol keeps
145
+ * as it is. `amount` and `contentSha256` are null only when the effect is
146
+ * reconstructed after the fact and they are no longer known — never guessed.
147
+ */
148
+ export interface PaymentReminderEffect {
149
+ kind: "payment_reminder";
150
+ to: string;
151
+ cc: string[];
152
+ test: boolean;
153
+ /** The invoice's voucher number. */
154
+ invoice: string;
155
+ invoiceId: string;
156
+ /** The open amount the mail stated. */
157
+ amount: number | null;
158
+ currency: string;
159
+ /** sha256 of the mail's content, see mailContentSha256. */
160
+ contentSha256: string | null;
161
+ }
162
+ /**
163
+ * The effect of a reminder sent to `target`. Pass the send's outcome; pass
164
+ * null to reconstruct it from the target alone, which leaves amount and hash
165
+ * unknown (null).
166
+ */
167
+ export declare function paymentReminderEffect(target: ReminderTarget, sent: {
168
+ openAmount: number;
169
+ contentSha256: string;
170
+ } | null): PaymentReminderEffect;
141
171
  /**
142
172
  * Sends one reminder, at most once per round: re-checks that the invoice is
143
173
  * still overdue, claims the round, renders and sends with the invoice PDF,
@@ -153,4 +183,10 @@ export declare function sendReminder(client: LexwareClient, ledger: ReminderLedg
153
183
  sessionId?: string;
154
184
  signal?: AbortSignal;
155
185
  }): Promise<SendReminderOutcome>;
186
+ /**
187
+ * The fingerprint of a mail's content: subject, plain text and HTML, joined
188
+ * with a separator that cannot occur in them. The same mail always gives the
189
+ * same hash; a protocol can keep it instead of the mail.
190
+ */
191
+ export declare function mailContentSha256(mail: Pick<ReminderMail, "subject" | "html" | "text">): string;
156
192
  export {};
package/dist/reminders.js CHANGED
@@ -16,6 +16,7 @@
16
16
  import { contactEmail } from "./contacts.js";
17
17
  import { addDays, daysSince } from "./dates.js";
18
18
  import { downloadInvoicePdf, findOverdueInvoice, findOverdueInvoices } from "./receivables.js";
19
+ import { createHash } from "node:crypto";
19
20
  import { MailNotSentError } from "./reminder-mail.js";
20
21
  import { keySegment } from "./store.js";
21
22
  export const DEFAULT_REMINDER_POLICY = {
@@ -121,6 +122,24 @@ export async function selectDueReminders(client, ledger, options = {}) {
121
122
  held: checked.flatMap(({ invoice, hold }) => (hold ? [{ invoice, hold }] : [])),
122
123
  };
123
124
  }
125
+ /**
126
+ * The effect of a reminder sent to `target`. Pass the send's outcome; pass
127
+ * null to reconstruct it from the target alone, which leaves amount and hash
128
+ * unknown (null).
129
+ */
130
+ export function paymentReminderEffect(target, sent) {
131
+ return {
132
+ kind: "payment_reminder",
133
+ to: target.to,
134
+ cc: [...(target.cc ?? [])],
135
+ test: target.test,
136
+ invoice: target.voucherNumber,
137
+ invoiceId: target.invoiceId,
138
+ amount: sent?.openAmount ?? null,
139
+ currency: target.currency,
140
+ contentSha256: sent?.contentSha256 ?? null,
141
+ };
142
+ }
124
143
  /**
125
144
  * Sends one reminder, at most once per round: re-checks that the invoice is
126
145
  * still overdue, claims the round, renders and sends with the invoice PDF,
@@ -171,5 +190,13 @@ export async function sendReminder(client, ledger, target, options) {
171
190
  ...(options.sessionId ? { sessionId: options.sessionId } : {}),
172
191
  })
173
192
  .catch(() => { });
174
- return { sent: true, openAmount: still.openAmount, attachment: mail.attachments[0].filename };
193
+ return { sent: true, openAmount: still.openAmount, attachment: mail.attachments[0].filename, contentSha256: mailContentSha256(mail) };
194
+ }
195
+ /**
196
+ * The fingerprint of a mail's content: subject, plain text and HTML, joined
197
+ * with a separator that cannot occur in them. The same mail always gives the
198
+ * same hash; a protocol can keep it instead of the mail.
199
+ */
200
+ export function mailContentSha256(mail) {
201
+ return createHash("sha256").update([mail.subject, mail.text ?? "", mail.html].join("\u0000")).digest("hex");
175
202
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kevludwig/lexware-office",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Typed client and domain logic for the Lexware Office Public API: contacts, receivables, payment reminder rules.",
5
5
  "type": "module",
6
6
  "license": "MIT",