@powerhousedao/contributor-billing 0.0.68 → 0.0.70
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/editors/invoice/InvoicePDF.js +1 -1
- package/dist/editors/invoice/ingestPDF.js +1 -1
- package/dist/editors/invoice/invoiceToGnosis.js +2 -2
- package/dist/editors/invoice/lineItems.d.ts.map +1 -1
- package/dist/editors/invoice/lineItems.js +93 -16
- package/dist/editors/invoice/requestFinance.d.ts.map +1 -1
- package/dist/editors/invoice/requestFinance.js +22 -8
- package/dist/editors/invoice/uploadPdfChunked.js +1 -1
- package/dist/scripts/invoice/gnosisTransactionBuilder.js +1 -1
- package/package.json +1 -1
|
@@ -412,4 +412,4 @@ const PaymentSectionCrypto = ({ paymentRouting, }) => (_jsx(View, { style: style
|
|
|
412
412
|
{
|
|
413
413
|
/* New component for line items */
|
|
414
414
|
}
|
|
415
|
-
const InvoiceLineItem = ({ item, currency, }) => (_jsxs(View, { style: styles.tableRow, children: [_jsxs(View, { style: styles.tableCol40, children: [_jsx(Text, { style: styles.itemName, children: item.description }), item.longDescription && (_jsx(Text, { style: styles.itemDescription, children: item.longDescription }))] }), _jsx(Text, { style: styles.tableCol15, children: item.quantity }), _jsx(Text, { style: styles.tableCol15, children: formatCurrency(item.unitPriceTaxExcl, currency) }), _jsx(Text, { style: styles.tableCol15, children: formatCurrency(item.unitPriceTaxIncl - item.unitPriceTaxExcl, currency) }), _jsx(Text, { style: styles.tableCol15, children: formatCurrency(item.quantity * item.unitPriceTaxIncl, currency) })] }));
|
|
415
|
+
const InvoiceLineItem = ({ item, currency, }) => (_jsxs(View, { style: styles.tableRow, children: [_jsxs(View, { style: styles.tableCol40, children: [_jsx(Text, { style: styles.itemName, children: item.description }), item.longDescription && (_jsx(Text, { style: styles.itemDescription, children: item.longDescription }))] }), _jsx(Text, { style: styles.tableCol15, children: item.quantity % 1 === 0 ? item.quantity.toString() : item.quantity.toFixed(2) }), _jsx(Text, { style: styles.tableCol15, children: formatCurrency(item.unitPriceTaxExcl, currency) }), _jsx(Text, { style: styles.tableCol15, children: formatCurrency(item.unitPriceTaxIncl - item.unitPriceTaxExcl, currency) }), _jsx(Text, { style: styles.tableCol15, children: formatCurrency(item.quantity * item.unitPriceTaxIncl, currency) })] }));
|
|
@@ -6,7 +6,7 @@ import { uploadPdfChunked } from "./uploadPdfChunked.js";
|
|
|
6
6
|
import { getCountryCodeFromName } from "./utils/utils.js";
|
|
7
7
|
let GRAPHQL_URL = 'http://localhost:4001/graphql/invoice';
|
|
8
8
|
if (!window.document.baseURI.includes('localhost')) {
|
|
9
|
-
GRAPHQL_URL = 'https://switchboard.powerhouse.xyz/graphql/invoice';
|
|
9
|
+
GRAPHQL_URL = 'https://switchboard-staging.powerhouse.xyz/graphql/invoice';
|
|
10
10
|
}
|
|
11
11
|
export async function loadPDFFile({ file, dispatch, }) {
|
|
12
12
|
if (!file)
|
|
@@ -4,7 +4,7 @@ import { actions } from "../../document-models/invoice/index.js";
|
|
|
4
4
|
import { generateId } from "document-model";
|
|
5
5
|
let GRAPHQL_URL = "http://localhost:4001/graphql/invoice";
|
|
6
6
|
if (!window.document.baseURI.includes('localhost')) {
|
|
7
|
-
GRAPHQL_URL = 'https://switchboard.powerhouse.xyz/graphql/invoice';
|
|
7
|
+
GRAPHQL_URL = 'https://switchboard-staging.powerhouse.xyz/graphql/invoice';
|
|
8
8
|
}
|
|
9
9
|
const InvoiceToGnosis = ({ docState, dispatch, }) => {
|
|
10
10
|
const [isLoading, setIsLoading] = useState(false);
|
|
@@ -157,7 +157,7 @@ const InvoiceToGnosis = ({ docState, dispatch, }) => {
|
|
|
157
157
|
? "Processing..."
|
|
158
158
|
: invoiceStatus === "ACCEPTED"
|
|
159
159
|
? "Schedule Payment in Gnosis Safe"
|
|
160
|
-
: "Reschedule Payment in Gnosis Safe" })), error && (_jsx("div", { className: "text-red-500 bg-red-50 p-3 rounded-md", children: error })), safeTxHash && (_jsxs("div", { className: "bg-gray-50 mt-4 rounded-md space-y-2", children: [_jsx("a", { href: `https://app.safe.global/transactions/queue?safe=${urlChainName}:
|
|
160
|
+
: "Reschedule Payment in Gnosis Safe" })), error && (_jsx("div", { className: "text-red-500 bg-red-50 p-3 rounded-md", children: error })), safeTxHash && (_jsxs("div", { className: "bg-gray-50 mt-4 rounded-md space-y-2", children: [_jsx("a", { href: `https://app.safe.global/transactions/queue?safe=${urlChainName}:0x1FB6bEF04230d67aF0e3455B997a28AFcCe1F45e`, target: "_blank", rel: "noopener noreferrer", className: "text-blue-500 hover:text-blue-600 underline block", children: linkText }), _jsxs("p", { className: "font-medium", children: ["Safe Transaction Hash:", _jsx("span", { className: "font-mono text-sm ml-2 break-all", children: safeTxHash })] })] })), !safeTxHash &&
|
|
161
161
|
!error &&
|
|
162
162
|
invoiceStatus === "PAYMENTSCHEDULED" &&
|
|
163
163
|
docState.payments.length > 0 && (_jsx(_Fragment, { children: docState.payments[docState.payments.length - 1].issue !== "" ? (_jsx("div", { className: "mt-4", children: _jsxs("p", { className: "text-red-700 font-medium", children: ["Issue: ", docState.payments[docState.payments.length - 1].issue] }) })) : (_jsxs("div", { className: "mt-4", children: [_jsx("div", { className: "invoice-link text-blue-900 hover:text-blue-600", children: _jsx("a", { className: "view-invoice-button", href: `https://app.safe.global/transactions/queue?safe=${urlChainName}:0x1FB6bEF04230d67aF0e3455B997a28AFcCe1F45e`, target: "_blank", rel: "noopener noreferrer", children: linkText }) }), _jsxs("p", { className: "mt-4 font-medium", children: ["Safe Transaction Hash:", _jsx("span", { className: "font-mono text-sm ml-2 break-all", children: docState.payments[docState.payments.length - 1]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lineItems.d.ts","sourceRoot":"","sources":["../../../editors/invoice/lineItems.tsx"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,UAAU,EAChB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAKL,KAAK,QAAQ,EAEd,MAAM,OAAO,CAAC;AAYf,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKlD;AAED,KAAK,QAAQ,GAAG;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,UAAU,EAAE,CAAC;CAC3B,CAAC;
|
|
1
|
+
{"version":3,"file":"lineItems.d.ts","sourceRoot":"","sources":["../../../editors/invoice/lineItems.tsx"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,UAAU,EAChB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAKL,KAAK,QAAQ,EAEd,MAAM,OAAO,CAAC;AAYf,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKlD;AAED,KAAK,QAAQ,GAAG;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,UAAU,EAAE,CAAC;CAC3B,CAAC;AAobF,KAAK,mBAAmB,GAAG;IACzB,QAAQ,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;IAC7C,QAAQ,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;IAChD,QAAQ,CAAC,YAAY,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAC5D,QAAQ,CAAC,gBAAgB,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC7D,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAC7B,MAAM,EAAE;QACN,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,gBAAgB,EAAE,MAAM,CAAC;QACzB,gBAAgB,EAAE,MAAM,CAAC;KAC1B,GAAG,IAAI,KACL,IAAI,CAAC;IACV,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC;IACjC,QAAQ,CAAC,eAAe,EAAE,UAAU,EAAE,CAAC;CACxC,CAAC;AAEF,wBAAgB,cAAc,CAAC,EAC7B,SAAS,EACT,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,QAAQ,EACR,eAAe,GAChB,EAAE,mBAAmB,2CAsSrB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { RWAButton } from "@powerhousedao/design-system";
|
|
2
|
+
import { RWAButton, toast } from "@powerhousedao/design-system";
|
|
3
3
|
import { forwardRef, useState, useMemo, useRef, useEffect, } from "react";
|
|
4
4
|
import { generateId } from "document-model";
|
|
5
5
|
import { Tag } from "lucide-react";
|
|
@@ -21,7 +21,7 @@ const EditableLineItem = forwardRef(function EditableLineItem(props, ref) {
|
|
|
21
21
|
const [editedItem, setEditedItem] = useState({
|
|
22
22
|
...item,
|
|
23
23
|
currency,
|
|
24
|
-
quantity: item.quantity ??
|
|
24
|
+
quantity: item.quantity ?? 1,
|
|
25
25
|
taxPercent: item.taxPercent ?? "",
|
|
26
26
|
unitPriceTaxExcl: item.unitPriceTaxExcl ?? "",
|
|
27
27
|
totalPriceTaxExcl: item.totalPriceTaxExcl ?? "",
|
|
@@ -30,9 +30,9 @@ const EditableLineItem = forwardRef(function EditableLineItem(props, ref) {
|
|
|
30
30
|
const calculatedValues = useMemo(() => {
|
|
31
31
|
const quantity = typeof editedItem.quantity === "string"
|
|
32
32
|
? editedItem.quantity === ""
|
|
33
|
-
?
|
|
34
|
-
: Number(editedItem.quantity)
|
|
35
|
-
: (editedItem.quantity ??
|
|
33
|
+
? 1
|
|
34
|
+
: Number(editedItem.quantity) || 1
|
|
35
|
+
: (editedItem.quantity ?? 1);
|
|
36
36
|
const unitPriceTaxExcl = typeof editedItem.unitPriceTaxExcl === "string"
|
|
37
37
|
? editedItem.unitPriceTaxExcl === ""
|
|
38
38
|
? 0
|
|
@@ -147,15 +147,21 @@ const EditableLineItem = forwardRef(function EditableLineItem(props, ref) {
|
|
|
147
147
|
setEditedItem((prev) => ({ ...prev, [field]: value }));
|
|
148
148
|
return;
|
|
149
149
|
}
|
|
150
|
-
// For numeric fields
|
|
151
|
-
if (value === "" || value === "0") {
|
|
150
|
+
// For numeric fields (except quantity which is handled separately)
|
|
151
|
+
if (field !== "quantity" && (value === "" || value === "0")) {
|
|
152
152
|
setEditedItem((prev) => ({ ...prev, [field]: value }));
|
|
153
153
|
return;
|
|
154
154
|
}
|
|
155
155
|
if (field === "quantity") {
|
|
156
|
-
// Allow
|
|
157
|
-
if (
|
|
158
|
-
setEditedItem((prev) => ({ ...prev, [field]:
|
|
156
|
+
// Allow up to 2 decimal places for quantity, default to 1 if empty or invalid
|
|
157
|
+
if (value === "" || value === "0") {
|
|
158
|
+
setEditedItem((prev) => ({ ...prev, [field]: 1 }));
|
|
159
|
+
}
|
|
160
|
+
else if (/^\d*\.?\d{0,2}$/.test(value)) {
|
|
161
|
+
setEditedItem((prev) => ({
|
|
162
|
+
...prev,
|
|
163
|
+
[field]: parseFloat(value) || 1,
|
|
164
|
+
}));
|
|
159
165
|
}
|
|
160
166
|
}
|
|
161
167
|
else if (field === "taxPercent") {
|
|
@@ -268,9 +274,9 @@ const EditableLineItem = forwardRef(function EditableLineItem(props, ref) {
|
|
|
268
274
|
}
|
|
269
275
|
return (_jsxs("tr", { ref: ref, className: "hover:bg-gray-50 table-row", children: [_jsx("td", { className: "border border-gray-200 p-3 table-cell", children: _jsx(InputField, { onBlur: () => { }, handleInputChange: (e) => {
|
|
270
276
|
setEditedItem((prev) => ({ ...prev, description: e.target.value }));
|
|
271
|
-
}, value: editedItem.description ?? "", placeholder: "Description", className: "" }) }), _jsx("td", { className: "border border-gray-200 p-3 table-cell", children: _jsx(NumberForm, { number: calculatedValues.quantity, precision:
|
|
277
|
+
}, value: editedItem.description ?? "", placeholder: "Description", className: "" }) }), _jsx("td", { className: "border border-gray-200 p-3 table-cell", children: _jsx(NumberForm, { number: calculatedValues.quantity || 1, precision: 2, handleInputChange: handleInputChange("quantity"), placeholder: "Quantity", className: "" }) }), _jsx("td", { className: "border border-gray-200 p-3 table-cell", children: _jsx(NumberForm, { number: calculatedValues.unitPriceTaxExcl % 1 === 0
|
|
272
278
|
? calculatedValues.unitPriceTaxExcl.toString()
|
|
273
|
-
: calculatedValues.unitPriceTaxExcl.toFixed(2), precision: 2, handleInputChange: handleInputChange("unitPriceTaxExcl"), pattern: "^-?\\d*\\.?\\d*$", placeholder: "Unit Price (excl. tax)", className: "" }) }), _jsx("td", { className: "border border-gray-200 p-3 table-cell", children: _jsx(NumberForm, { number: calculatedValues.taxPercent, precision: 0, pattern: "^(100|[1-9]?[0-9])$", handleInputChange: handleInputChange("taxPercent"), placeholder: "Tax %", className: "" }) }), _jsx("td", { className: "border border-gray-200 p-3 text-right font-medium table-cell", children: _jsx(NumberForm, { number: calculatedValues.totalPriceTaxExcl % 1 === 0
|
|
279
|
+
: calculatedValues.unitPriceTaxExcl.toFixed(2), precision: 2, handleInputChange: handleInputChange("unitPriceTaxExcl"), pattern: "^-?\\d*\\.?\\d*$", placeholder: "Unit Price (excl. tax)", className: "" }) }), _jsx("td", { className: "border border-gray-200 p-3 text-right font-medium table-cell", children: _jsx(NumberForm, { number: calculatedValues.taxPercent, precision: 0, pattern: "^(100|[1-9]?[0-9])$", handleInputChange: handleInputChange("taxPercent"), placeholder: "Tax %", className: "" }) }), _jsx("td", { className: "border border-gray-200 p-3 text-right font-medium table-cell", children: _jsx(NumberForm, { number: calculatedValues.totalPriceTaxExcl % 1 === 0
|
|
274
280
|
? calculatedValues.totalPriceTaxExcl.toString()
|
|
275
281
|
: calculatedValues.totalPriceTaxExcl.toFixed(2), precision: 2, handleInputChange: handleInputChange("totalPriceTaxExcl"), pattern: "^-?\\d*\\.?\\d*$", placeholder: "Total (excl. tax)", className: "" }) }), _jsx("td", { className: "border border-gray-200 p-3 text-right font-medium table-cell", children: _jsx(NumberForm, { number: calculatedValues.totalPriceTaxIncl % 1 === 0
|
|
276
282
|
? calculatedValues.totalPriceTaxIncl.toString()
|
|
@@ -288,7 +294,41 @@ export function LineItemsTable({ lineItems, currency, onAddItem, onUpdateItem, o
|
|
|
288
294
|
setIsAddingNew(true);
|
|
289
295
|
}
|
|
290
296
|
function handleSaveNewItem(item) {
|
|
291
|
-
|
|
297
|
+
try {
|
|
298
|
+
onAddItem(item);
|
|
299
|
+
}
|
|
300
|
+
catch (error) {
|
|
301
|
+
if (error?.message?.includes("Invalid action input:")) {
|
|
302
|
+
try {
|
|
303
|
+
const errorPart = error.message.split("Invalid action input: ")[1];
|
|
304
|
+
const zodError = JSON.parse(errorPart);
|
|
305
|
+
if (Array.isArray(zodError) && zodError.length > 0) {
|
|
306
|
+
const firstError = zodError[0];
|
|
307
|
+
const errorJSX = (_jsxs("div", { children: [_jsx("p", { className: "font-semibold", children: "Failed to add line item" }), _jsxs("p", { children: [firstError.message, ": "] }), zodError.map((err, index) => (_jsx("ul", { children: _jsxs("li", { className: "text-red-500 font-semibold", children: ["- ", err.path.join(".")] }) }, index)))] }));
|
|
308
|
+
toast(errorJSX, {
|
|
309
|
+
type: "error",
|
|
310
|
+
});
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
catch (parseError) {
|
|
315
|
+
console.error("Failed to parse Zod error:", parseError);
|
|
316
|
+
toast("Invalid input data", {
|
|
317
|
+
type: "error",
|
|
318
|
+
});
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
else if (error?.message) {
|
|
323
|
+
toast(error.message, {
|
|
324
|
+
type: "error",
|
|
325
|
+
});
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
toast("Failed to add line item", {
|
|
329
|
+
type: "error",
|
|
330
|
+
});
|
|
331
|
+
}
|
|
292
332
|
setIsAddingNew(false);
|
|
293
333
|
}
|
|
294
334
|
function handleCancelNewItem() {
|
|
@@ -313,9 +353,46 @@ export function LineItemsTable({ lineItems, currency, onAddItem, onUpdateItem, o
|
|
|
313
353
|
color: "white",
|
|
314
354
|
fill: "#475264",
|
|
315
355
|
} })] }) })] }) }), _jsxs("tbody", { children: [lineItems.map((item) => editingId === item.id ? (_jsx(EditableLineItem, { currency: currency, item: item, onCancel: () => setEditingId(null), onSave: (updatedItem) => {
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
356
|
+
try {
|
|
357
|
+
onUpdateItem(updatedItem);
|
|
358
|
+
setEditingId(null);
|
|
359
|
+
}
|
|
360
|
+
catch (error) {
|
|
361
|
+
console.error(error);
|
|
362
|
+
if (error?.message?.includes("Invalid action input:")) {
|
|
363
|
+
try {
|
|
364
|
+
const zodError = JSON.parse(error.message.split("Invalid action input: ")[1]);
|
|
365
|
+
if (Array.isArray(zodError) &&
|
|
366
|
+
zodError.length > 0) {
|
|
367
|
+
const firstError = zodError[0];
|
|
368
|
+
const errorJSX = (_jsxs("div", { children: [_jsx("p", { className: "font-semibold", children: "Failed to update line item" }), _jsxs("p", { children: [firstError.message, ": "] }), zodError.map((err, index) => (_jsx("ul", { children: _jsxs("li", { className: "text-red-500 font-semibold", children: ["- ", err.path.join(".")] }) }, index)))] }));
|
|
369
|
+
toast(errorJSX, {
|
|
370
|
+
type: "error",
|
|
371
|
+
});
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
catch (parseError) {
|
|
376
|
+
console.error("Failed to parse Zod error:", parseError);
|
|
377
|
+
toast("Invalid input data", {
|
|
378
|
+
type: "error",
|
|
379
|
+
});
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
else if (error?.message) {
|
|
384
|
+
toast(error.message, {
|
|
385
|
+
type: "error",
|
|
386
|
+
});
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
toast("Failed to update line item", {
|
|
390
|
+
type: "error",
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
}, onEditingItemChange: onEditingItemChange }, item.id)) : (_jsxs("tr", { className: "hover:bg-gray-50 table-row", children: [_jsx("td", { className: "border-b border-gray-200 p-3 table-cell", children: item.description }), _jsx("td", { className: "border-b border-gray-200 p-3 text-right table-cell", children: item.quantity % 1 === 0
|
|
394
|
+
? item.quantity.toString()
|
|
395
|
+
: item.quantity.toFixed(2) }), _jsx("td", { className: "border-b border-gray-200 p-3 text-right table-cell", children: formatNumber(item.unitPriceTaxExcl) }), _jsxs("td", { className: "border-b border-gray-200 p-3 text-right table-cell", children: [typeof item.taxPercent === "number"
|
|
319
396
|
? Math.round(item.taxPercent)
|
|
320
397
|
: 0, "%"] }), _jsx("td", { className: "border-b border-gray-200 p-3 text-right font-medium table-cell", children: formatNumber(item.totalPriceTaxExcl) }), _jsx("td", { className: "border-b border-gray-200 p-3 text-right font-medium table-cell", children: formatNumber(item.totalPriceTaxIncl) }), _jsx("td", { className: "border-b border-gray-200 p-3 table-cell", children: _jsxs("div", { className: "flex justify-center space-x-2", children: [_jsx("button", { className: "rounded bg-blue-500 px-3 py-1 text-white hover:bg-blue-200", onClick: () => setEditingId(item.id), children: "Edit" }), _jsx("button", { className: "rounded bg-red-600 px-3 py-1 text-white hover:bg-red-700", onClick: () => onDeleteItem({ id: item.id }), children: "Delete" })] }) })] }, item.id))), isAddingNew ? (_jsx(EditableLineItem, { currency: currency, item: {}, onCancel: handleCancelNewItem, onSave: handleSaveNewItem, onEditingItemChange: onEditingItemChange })) : null] })] }) })] }) }));
|
|
321
398
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requestFinance.d.ts","sourceRoot":"","sources":["../../../editors/invoice/requestFinance.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAUxC,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,GAAG,CAAC;IACd,QAAQ,EAAE,GAAG,CAAC;CACf;AAED,QAAA,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,
|
|
1
|
+
{"version":3,"file":"requestFinance.d.ts","sourceRoot":"","sources":["../../../editors/invoice/requestFinance.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAUxC,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,GAAG,CAAC;IACd,QAAQ,EAAE,GAAG,CAAC;CACf;AAED,QAAA,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAgRjD,CAAC;AAEF,eAAe,cAAc,CAAC"}
|
|
@@ -4,7 +4,7 @@ import { actions } from "../../document-models/invoice/index.js";
|
|
|
4
4
|
import { generateId } from "document-model";
|
|
5
5
|
let GRAPHQL_URL = "http://localhost:4001/graphql/invoice";
|
|
6
6
|
if (!window.document.baseURI.includes('localhost')) {
|
|
7
|
-
GRAPHQL_URL = 'https://switchboard.powerhouse.xyz/graphql/invoice';
|
|
7
|
+
GRAPHQL_URL = 'https://switchboard-staging.powerhouse.xyz/graphql/invoice';
|
|
8
8
|
}
|
|
9
9
|
const RequestFinance = ({ docState, dispatch, }) => {
|
|
10
10
|
const [isLoading, setIsLoading] = useState(false);
|
|
@@ -73,6 +73,14 @@ const RequestFinance = ({ docState, dispatch, }) => {
|
|
|
73
73
|
"Liberty",
|
|
74
74
|
bicSwift: docState.issuer.paymentRouting.bank.BIC,
|
|
75
75
|
};
|
|
76
|
+
const getDecimalPlaces = (currency) => {
|
|
77
|
+
const formatter = new Intl.NumberFormat("en-US", {
|
|
78
|
+
style: "currency",
|
|
79
|
+
currency,
|
|
80
|
+
minimumFractionDigits: 0, // Ensure we get the default for the currency
|
|
81
|
+
});
|
|
82
|
+
return formatter.resolvedOptions().maximumFractionDigits ?? 2;
|
|
83
|
+
};
|
|
76
84
|
try {
|
|
77
85
|
const invoiceData = {
|
|
78
86
|
meta: {
|
|
@@ -80,12 +88,18 @@ const RequestFinance = ({ docState, dispatch, }) => {
|
|
|
80
88
|
version: "0.0.3",
|
|
81
89
|
},
|
|
82
90
|
creationDate: docState.dateIssued,
|
|
83
|
-
invoiceItems: docState.lineItems.map((item) =>
|
|
84
|
-
currency
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
91
|
+
invoiceItems: docState.lineItems.map((item) => {
|
|
92
|
+
const currency = bankDetails.currency;
|
|
93
|
+
const decimalPlaces = getDecimalPlaces(currency);
|
|
94
|
+
const multiplier = Math.pow(10, decimalPlaces);
|
|
95
|
+
const unitPriceInt = Math.round(item.unitPriceTaxIncl * multiplier);
|
|
96
|
+
return {
|
|
97
|
+
currency,
|
|
98
|
+
name: item.description,
|
|
99
|
+
quantity: item.quantity,
|
|
100
|
+
unitPrice: unitPriceInt,
|
|
101
|
+
};
|
|
102
|
+
}),
|
|
89
103
|
invoiceNumber: docState.invoiceNo,
|
|
90
104
|
buyerInfo: {
|
|
91
105
|
// email: docState.payer.contactInfo.email,
|
|
@@ -135,7 +149,7 @@ const RequestFinance = ({ docState, dispatch, }) => {
|
|
|
135
149
|
};
|
|
136
150
|
// Instead of calling the API endpoint directly, use the createDirectPayment function
|
|
137
151
|
const directPaymentResult = await createDirectPayment(invoiceData);
|
|
138
|
-
console.log("Direct payment created:", directPaymentResult);
|
|
152
|
+
console.log("Direct payment created: (unitPrice in cents)", directPaymentResult);
|
|
139
153
|
// Process the response
|
|
140
154
|
if (directPaymentResult?.response?.invoiceLinks?.pay) {
|
|
141
155
|
setInvoiceLink(directPaymentResult.response.invoiceLinks.pay);
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
let GRAPHQL_URL = 'http://localhost:4001/graphql/invoice';
|
|
9
9
|
if (!window.document.baseURI.includes('localhost')) {
|
|
10
|
-
GRAPHQL_URL = 'https://switchboard.powerhouse.xyz/graphql/invoice';
|
|
10
|
+
GRAPHQL_URL = 'https://switchboard-staging.powerhouse.xyz/graphql/invoice';
|
|
11
11
|
}
|
|
12
12
|
export async function uploadPdfChunked(pdfData, endpoint = GRAPHQL_URL, chunkSize = 500 * 1024, // 500KB chunks
|
|
13
13
|
onProgress) {
|
|
@@ -4,7 +4,7 @@ import { OperationType } from '@safe-global/types-kit';
|
|
|
4
4
|
import { ethers, AbiCoder } from 'ethers';
|
|
5
5
|
import dotenv from 'dotenv';
|
|
6
6
|
dotenv.config();
|
|
7
|
-
const safeAddress = process.env.
|
|
7
|
+
const safeAddress = process.env.DEV_STAGING_SAFE_ADDRESS;
|
|
8
8
|
if (!safeAddress) {
|
|
9
9
|
throw new Error('Missing SAFE_ADDRESS in .env');
|
|
10
10
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@powerhousedao/contributor-billing",
|
|
3
3
|
"description": "Document models that help contributors of open organisations get paid anonymously for their work on a monthly basis.",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.70",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"files": [
|