@powerhousedao/contributor-billing 0.0.8 → 0.0.9
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/document-models/invoice/gen/document-model.d.ts.map +1 -1
- package/dist/document-models/invoice/gen/document-model.js +27 -5
- package/dist/document-models/invoice/gen/general/actions.d.ts +5 -3
- package/dist/document-models/invoice/gen/general/actions.d.ts.map +1 -1
- package/dist/document-models/invoice/gen/general/creators.d.ts +5 -3
- package/dist/document-models/invoice/gen/general/creators.d.ts.map +1 -1
- package/dist/document-models/invoice/gen/general/creators.js +3 -1
- package/dist/document-models/invoice/gen/general/object.d.ts +4 -2
- package/dist/document-models/invoice/gen/general/object.d.ts.map +1 -1
- package/dist/document-models/invoice/gen/general/object.js +9 -3
- package/dist/document-models/invoice/gen/general/operations.d.ts +4 -2
- package/dist/document-models/invoice/gen/general/operations.d.ts.map +1 -1
- package/dist/document-models/invoice/gen/reducer.d.ts.map +1 -1
- package/dist/document-models/invoice/gen/reducer.js +11 -3
- package/dist/document-models/invoice/gen/schema/types.d.ts +13 -6
- package/dist/document-models/invoice/gen/schema/types.d.ts.map +1 -1
- package/dist/document-models/invoice/gen/schema/zod.d.ts +4 -2
- package/dist/document-models/invoice/gen/schema/zod.d.ts.map +1 -1
- package/dist/document-models/invoice/gen/schema/zod.js +19 -8
- package/dist/document-models/invoice/gen/utils.js +1 -1
- package/dist/document-models/invoice/index.d.ts +3 -1
- package/dist/document-models/invoice/index.d.ts.map +1 -1
- package/dist/document-models/invoice/src/reducers/general.d.ts.map +1 -1
- package/dist/document-models/invoice/src/reducers/general.js +30 -2
- package/dist/document-models/invoice/src/reducers/items.d.ts.map +1 -1
- package/dist/document-models/invoice/src/reducers/items.js +17 -10
- package/dist/document-models/invoice/src/tests/general.test.js +2 -2
- package/dist/editors/invoice/InvoicePDF.d.ts.map +1 -1
- package/dist/editors/invoice/InvoicePDF.js +11 -12
- package/dist/editors/invoice/editor.d.ts.map +1 -1
- package/dist/editors/invoice/editor.js +6 -17
- package/dist/editors/invoice/ingestPDF.js +1 -1
- package/dist/editors/invoice/invoiceToGnosis.d.ts.map +1 -1
- package/dist/editors/invoice/invoiceToGnosis.js +4 -25
- package/dist/editors/invoice/lineItemTags/lineItemTags.d.ts +20 -0
- package/dist/editors/invoice/lineItemTags/lineItemTags.d.ts.map +1 -0
- package/dist/editors/invoice/lineItemTags/lineItemTags.js +47 -0
- package/dist/editors/invoice/lineItemTags/tagMapping.d.ts +3 -0
- package/dist/editors/invoice/lineItemTags/tagMapping.d.ts.map +1 -0
- package/dist/editors/invoice/lineItemTags/tagMapping.js +62 -0
- package/dist/editors/invoice/lineItems.d.ts +7 -2
- package/dist/editors/invoice/lineItems.d.ts.map +1 -1
- package/dist/editors/invoice/lineItems.js +44 -15
- package/dist/editors/invoice/requestFinance.js +1 -1
- package/dist/editors/invoice/uploadPdfChunked.js +1 -1
- package/dist/scripts/invoice/exampleBatchTxn.js +1 -1
- package/dist/scripts/invoice/gnosisTransactionBuilder.d.ts +1 -1
- package/dist/scripts/invoice/gnosisTransactionBuilder.d.ts.map +1 -1
- package/dist/scripts/invoice/gnosisTransactionBuilder.js +26 -1
- package/dist/style.css +13 -0
- package/dist/subgraphs/invoice/customResolvers.d.ts +1 -1
- package/dist/subgraphs/invoice/customResolvers.d.ts.map +1 -1
- package/dist/subgraphs/invoice/customResolvers.js +4 -5
- package/dist/subgraphs/invoice/resolvers.d.ts.map +1 -1
- package/dist/subgraphs/invoice/resolvers.js +16 -2
- package/dist/subgraphs/invoice/schema.d.ts.map +1 -1
- package/dist/subgraphs/invoice/schema.js +24 -7
- package/package.json +1 -1
|
@@ -53,18 +53,25 @@ export const reducer = {
|
|
|
53
53
|
},
|
|
54
54
|
setLineItemTagOperation(state, action, dispatch) {
|
|
55
55
|
try {
|
|
56
|
-
const stateItem = state.lineItems.find((x) => x.id === action.input.
|
|
56
|
+
const stateItem = state.lineItems.find((x) => x.id === action.input.lineItemId);
|
|
57
57
|
if (!stateItem)
|
|
58
58
|
throw new Error("Item matching input.id not found");
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
59
|
+
// if tag already exists with the same dimension, update the value and label
|
|
60
|
+
const existingTag = stateItem.lineItemTag?.find((tag) => tag.dimension === action.input.dimension);
|
|
61
|
+
if (existingTag) {
|
|
62
|
+
existingTag.value = action.input.value;
|
|
63
|
+
existingTag.label = action.input.label || null;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
// if tag does not exist, add it
|
|
67
|
+
const newTag = {
|
|
68
|
+
dimension: action.input.dimension,
|
|
69
|
+
value: action.input.value,
|
|
70
|
+
label: action.input.label || null,
|
|
71
|
+
};
|
|
72
|
+
// Add the new tag
|
|
73
|
+
stateItem.lineItemTag?.push(newTag);
|
|
74
|
+
}
|
|
68
75
|
}
|
|
69
76
|
catch (e) {
|
|
70
77
|
console.error(e);
|
|
@@ -65,8 +65,8 @@ describe("General Operations", () => {
|
|
|
65
65
|
it("should handle setPaymentAccount operation", () => {
|
|
66
66
|
// generate a random id
|
|
67
67
|
// const id = documentModelUtils.hashKey();
|
|
68
|
-
const input = generateMock(z.
|
|
69
|
-
const updatedDocument = reducer(document, creators.
|
|
68
|
+
const input = generateMock(z.AddPaymentAccountInputSchema());
|
|
69
|
+
const updatedDocument = reducer(document, creators.addPaymentAccount(input));
|
|
70
70
|
expect(updatedDocument.operations.global).toHaveLength(1);
|
|
71
71
|
expect(updatedDocument.operations.global[0].type).toBe("SET_PAYMENT_ACCOUNT");
|
|
72
72
|
expect(updatedDocument.operations.global[0].input).toStrictEqual(input);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InvoicePDF.d.ts","sourceRoot":"","sources":["../../../editors/invoice/InvoicePDF.tsx"],"names":[],"mappings":"AAQA,OAAO,EACL,YAAY,EAIb,MAAM,wCAAwC,CAAC;
|
|
1
|
+
{"version":3,"file":"InvoicePDF.d.ts","sourceRoot":"","sources":["../../../editors/invoice/InvoicePDF.tsx"],"names":[],"mappings":"AAQA,OAAO,EACL,YAAY,EAIb,MAAM,wCAAwC,CAAC;AAiThD,UAAU,eAAe;IACvB,OAAO,EAAE,YAAY,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CA0ZhD,CAAC"}
|
|
@@ -215,6 +215,11 @@ const styles = StyleSheet.create({
|
|
|
215
215
|
fontSize: 9,
|
|
216
216
|
color: "#4B5563",
|
|
217
217
|
marginBottom: 4,
|
|
218
|
+
flexShrink: 1,
|
|
219
|
+
flexGrow: 1,
|
|
220
|
+
minWidth: 0,
|
|
221
|
+
paddingRight: 1,
|
|
222
|
+
wordBreak: "break-all",
|
|
218
223
|
},
|
|
219
224
|
companyInfoLabel: {
|
|
220
225
|
color: "#9ea0a2",
|
|
@@ -305,22 +310,22 @@ export const InvoicePDF = ({ invoice, fiatMode, }) => {
|
|
|
305
310
|
}, children: [_jsxs(View, { style: {
|
|
306
311
|
flexDirection: "column",
|
|
307
312
|
alignItems: "flex-start",
|
|
308
|
-
}, children: [_jsx(Text, { style: { fontSize: 20, fontWeight: "bold" }, children: invoice.issuer.name }), _jsxs(View, { children: [_jsx(Text, { style: styles.invoiceLabel, children: "Invoice number" }), _jsx(Text, { style: styles.invoiceNumber, children: invoice.invoiceNo })] })] }), _jsxs(View, { style: { alignItems: "flex-end" }, children: [_jsxs(Text, { style: styles.invoiceLabel, children: ["Invoice of (", invoice.currency, ")"] }), _jsx(Text, { style: [
|
|
313
|
+
}, children: [_jsx(Text, { style: { fontSize: 20, fontWeight: "bold", marginBottom: 10, paddingRight: 65, marginRight: 20 }, children: invoice.issuer.name }), _jsxs(View, { children: [_jsx(Text, { style: styles.invoiceLabel, children: "Invoice number" }), _jsx(Text, { style: styles.invoiceNumber, children: invoice.invoiceNo })] })] }), _jsxs(View, { style: { alignItems: "flex-end" }, children: [_jsxs(Text, { style: styles.invoiceLabel, children: ["Invoice of (", invoice.currency, ")"] }), _jsx(Text, { style: [
|
|
309
314
|
styles.invoiceNumber,
|
|
310
315
|
{ fontSize: 18, fontWeight: "bold" },
|
|
311
316
|
], children: formatNumber(invoice.totalPriceTaxIncl) })] })] }), _jsxs(View, { style: {
|
|
312
317
|
flexDirection: "row",
|
|
313
318
|
justifyContent: "space-between",
|
|
314
319
|
marginTop: 20,
|
|
315
|
-
}, children: [_jsxs(View, { style: { width: "
|
|
320
|
+
}, children: [_jsxs(View, { style: { width: "50%", minWidth: 0, flexDirection: "column", paddingRight: 65 }, children: [_jsx(Text, { style: styles.sectionTitle, children: "Issuer" }), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Name:" }), _jsx(Text, { style: styles.companyInfo, wrap: true, children: invoice.issuer.name })] }), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Tax/Corp ID:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.issuer.id
|
|
316
321
|
?.taxId ||
|
|
317
322
|
invoice.issuer
|
|
318
323
|
.id?.corpRegId ||
|
|
319
|
-
"" })] }), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Address:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.issuer.address?.streetAddress || "" })] }), invoice.issuer.address?.extendedAddress && (_jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel }), _jsx(Text, { style: styles.companyInfo, children: invoice.issuer.address?.extendedAddress || "" })] })), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel }), _jsxs(Text, { style: styles.companyInfo, children: [invoice.issuer.address?.city || "", ",", " ", getCountryName(invoice.issuer.address?.country || "") || ""] })] }), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Postcode:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.issuer.address?.postalCode || "00000" })] }), invoice.issuer.contactInfo?.email && (_jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Email:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.issuer.contactInfo.email })] }))] }), _jsxs(View, { style: { width: "
|
|
324
|
+
"" })] }), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Address:" }), _jsx(Text, { style: styles.companyInfo, wrap: true, children: invoice.issuer.address?.streetAddress || "" })] }), invoice.issuer.address?.extendedAddress && (_jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel }), _jsx(Text, { style: styles.companyInfo, wrap: true, children: invoice.issuer.address?.extendedAddress || "" })] })), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel }), _jsxs(Text, { style: styles.companyInfo, wrap: true, children: [invoice.issuer.address?.city || "", ",", " ", getCountryName(invoice.issuer.address?.country || "") || ""] })] }), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Postcode:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.issuer.address?.postalCode || "00000" })] }), invoice.issuer.contactInfo?.email && (_jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Email:" }), _jsx(Text, { style: styles.companyInfo, wrap: true, children: invoice.issuer.contactInfo.email })] }))] }), _jsxs(View, { style: { width: "47%", minWidth: 0, flexDirection: "column" }, children: [_jsx(Text, { style: styles.sectionTitle, children: "Payer" }), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Name:" }), _jsx(Text, { style: styles.companyInfo, wrap: true, children: invoice.payer.name })] }), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Tax/Corp ID:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.payer.id?.taxId ||
|
|
320
325
|
invoice.payer
|
|
321
326
|
.id?.corpRegId ||
|
|
322
|
-
"" })] }), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Address:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.payer.address?.streetAddress || "" })] }), invoice.payer.address?.extendedAddress && (_jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel }), _jsx(Text, { style: styles.companyInfo, children: invoice.payer.address?.extendedAddress || "" })] })), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel }), _jsxs(Text, { style: styles.companyInfo, children: [invoice.payer.address?.city || "", ",", " ", getCountryName(invoice.payer.address?.country || "") ||
|
|
323
|
-
""] })] }), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Postcode:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.payer.address?.postalCode || "00000" })] }), invoice.payer.contactInfo?.email && (_jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Email:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.payer.contactInfo.email })] }))] }), _jsxs(View, { style: {
|
|
327
|
+
"" })] }), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Address:" }), _jsx(Text, { style: styles.companyInfo, wrap: true, children: invoice.payer.address?.streetAddress || "" })] }), invoice.payer.address?.extendedAddress && (_jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel }), _jsx(Text, { style: styles.companyInfo, wrap: true, children: invoice.payer.address?.extendedAddress || "" })] })), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel }), _jsxs(Text, { style: styles.companyInfo, wrap: true, children: [invoice.payer.address?.city || "", ",", " ", getCountryName(invoice.payer.address?.country || "") ||
|
|
328
|
+
""] })] }), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Postcode:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.payer.address?.postalCode || "00000" })] }), invoice.payer.contactInfo?.email && (_jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Email:" }), _jsx(Text, { style: styles.companyInfo, wrap: true, children: invoice.payer.contactInfo.email })] }))] }), _jsxs(View, { style: {
|
|
324
329
|
width: "30%",
|
|
325
330
|
alignItems: "flex-end",
|
|
326
331
|
textAlign: "right",
|
|
@@ -368,19 +373,13 @@ export const InvoicePDF = ({ invoice, fiatMode, }) => {
|
|
|
368
373
|
alignItems: "center",
|
|
369
374
|
justifyContent: "space-between",
|
|
370
375
|
width: "90%",
|
|
371
|
-
}, children: [
|
|
376
|
+
}, children: [_jsx(View, { children: _jsx(Text, { style: styles.termsText, children: "Please pay within 30 days of receiving this invoice." }) }), _jsx(Text, { style: {
|
|
372
377
|
fontSize: 10,
|
|
373
378
|
color: "#6B7280",
|
|
374
379
|
textAlign: "right",
|
|
375
380
|
flex: 1,
|
|
376
381
|
}, children: `${pageIndex + 1}/${totalPages}` })] })] }, pageIndex))) }));
|
|
377
382
|
};
|
|
378
|
-
// New component for issuer and payer sections
|
|
379
|
-
const InvoiceSection = ({ title, data, }) => (_jsxs(View, { style: styles.gridColumn, children: [_jsx(Text, { style: styles.sectionTitle, children: title }), title === "Issuer" && (_jsxs(_Fragment, { children: [_jsx(InvoiceField, { label: "Issue Date", value: formatDate(data.dateIssued) }), _jsx(InvoiceField, { label: "Delivery Date", value: formatDate(data.dateDelivered) })] })), title === "Payer" && (_jsx(InvoiceField, { label: "Due Date", value: formatDate(data.dateDue) })), _jsx(InvoiceField, { label: "Name", value: data.name }), _jsx(InvoiceField, { label: data.id?.taxId ? "Tax ID" : data.id?.corpRegId ? "Corp. Reg" : "", value: data.id?.taxId || data.id?.corpRegId || "" }), _jsx(InvoiceField, { label: "Address", value: data.address?.streetAddress || "" }), _jsx(InvoiceField, { label: "City", value: data.address?.city || "" }), _jsx(InvoiceField, { label: "Country", value: getCountryName(data.address?.country || "") || "" }), _jsx(InvoiceField, { label: "Email", value: data.contactInfo?.email || "" })] }));
|
|
380
|
-
{
|
|
381
|
-
/* New component for individual fields */
|
|
382
|
-
}
|
|
383
|
-
const InvoiceField = ({ label, value, }) => value && (_jsx(View, { style: styles.row, children: _jsx(Text, { style: styles.value, children: value }) }));
|
|
384
383
|
{
|
|
385
384
|
/* New component for fiat payment section */
|
|
386
385
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../editors/invoice/editor.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EACL,KAAK,eAAe,EAGrB,MAAM,wCAAwC,CAAC;
|
|
1
|
+
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../editors/invoice/editor.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EACL,KAAK,eAAe,EAGrB,MAAM,wCAAwC,CAAC;AA4BhD,MAAM,MAAM,MAAM,GAAG,WAAW,CAAC,eAAe,CAAC,CAAC;AAElD,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,KAAK,EAAE,MAAM,2CAouB3C"}
|
|
@@ -17,21 +17,7 @@ import { InputField } from "./components/inputField.js";
|
|
|
17
17
|
import { validateField, } from "./validation/validationManager.js";
|
|
18
18
|
import { DatePicker } from "./components/datePicker.js";
|
|
19
19
|
import { SelectField } from "./components/selectField.js";
|
|
20
|
-
|
|
21
|
-
function formatNumber(value) {
|
|
22
|
-
// Check if the value has decimal places
|
|
23
|
-
const hasDecimals = value % 1 !== 0;
|
|
24
|
-
// If no decimals or only trailing zeros after 2 decimal places, show 2 decimal places
|
|
25
|
-
if (!hasDecimals || value.toFixed(5).endsWith("000")) {
|
|
26
|
-
return value.toFixed(2);
|
|
27
|
-
}
|
|
28
|
-
// Otherwise, show actual decimal places up to 5
|
|
29
|
-
const stringValue = value.toString();
|
|
30
|
-
const decimalPart = stringValue.split(".")[1] || "";
|
|
31
|
-
// Determine how many decimal places to show (up to 5)
|
|
32
|
-
const decimalPlaces = Math.min(Math.max(2, decimalPart.length), 5);
|
|
33
|
-
return value.toFixed(decimalPlaces);
|
|
34
|
-
}
|
|
20
|
+
import { formatNumber } from "./lineItems.js";
|
|
35
21
|
function isFiatCurrency(currency) {
|
|
36
22
|
return currencyList.find((c) => c.ticker === currency)?.crypto === false;
|
|
37
23
|
}
|
|
@@ -370,8 +356,11 @@ export default function Editor(props) {
|
|
|
370
356
|
}
|
|
371
357
|
}, value: state.dateDelivered || "" })] })] }), _jsx(LegalEntityForm, { legalEntity: state.issuer, onChangeBank: (input) => dispatch(actions.editIssuerBank(input)), onChangeInfo: (input) => dispatch(actions.editIssuer(input)), onChangeWallet: (input) => dispatch(actions.editIssuerWallet(input)), bankDisabled: !fiatMode, walletDisabled: fiatMode, currency: state.currency, status: state.status, walletvalidation: walletValidation, countryvalidation: countryValidation, ibanvalidation: ibanValidation, bicvalidation: bicValidation, banknamevalidation: bankNameValidation, streetaddressvalidation: streetAddressValidation, cityvalidation: cityValidation, postalcodevalidation: postalCodeValidation })] }), _jsxs("div", { className: "border border-gray-200 rounded-lg p-6", children: [_jsx("h3", { className: "text-lg font-semibold mb-4", children: "Payer" }), _jsxs("div", { className: "mb-2", children: [_jsx("label", { className: "block mb-1 text-sm", children: "Due Date:" }), _jsx(DatePicker, { name: "dateDue", className: "w-full", onChange: (e) => dispatch(actions.editInvoice({
|
|
372
358
|
dateDue: e.target.value.split("T")[0],
|
|
373
|
-
})), value: state.dateDue })] }), _jsx(LegalEntityForm, { bankDisabled: true, legalEntity: state.payer, onChangeInfo: (input) => dispatch(actions.editPayer(input)), currency: state.currency, status: state.status, payeremailvalidation: payerEmailValidation })] })] }), _jsx("div", { className: "mb-8", children: _jsx(LineItemsTable, { currency: state.currency, lineItems: state.lineItems
|
|
359
|
+
})), value: state.dateDue })] }), _jsx(LegalEntityForm, { bankDisabled: true, legalEntity: state.payer, onChangeInfo: (input) => dispatch(actions.editPayer(input)), currency: state.currency, status: state.status, payeremailvalidation: payerEmailValidation })] })] }), _jsx("div", { className: "mb-8", children: _jsx(LineItemsTable, { currency: state.currency, lineItems: state.lineItems.map(item => ({
|
|
360
|
+
...item,
|
|
361
|
+
lineItemTag: item.lineItemTag ?? [],
|
|
362
|
+
})), onAddItem: (item) => dispatch(actions.addLineItem(item)), onDeleteItem: (input) => dispatch(actions.deleteLineItem(input)), onUpdateCurrency: (input) => {
|
|
374
363
|
setFiatMode(input.currency !== "USDS");
|
|
375
364
|
dispatch(actions.editInvoice(input));
|
|
376
|
-
}, onUpdateItem: (item) => dispatch(actions.editLineItem(item)) }) }), _jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6", children: _jsx("div", { className: "md:col-start-2", children: _jsx("div", { className: "rounded-lg border border-gray-200 bg-gray-50 p-6 shadow-sm", children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex justify-between text-gray-700", children: [_jsx("span", { className: "font-medium", children: "Subtotal (excl. tax):" }), _jsxs("span", { children: [formatNumber(itemsTotalTaxExcl), " ", state.currency] })] }), _jsxs("div", { className: "flex justify-between border-t border-gray-200 pt-4 text-lg font-bold text-gray-900", children: [_jsx("span", { children: "Total (incl. tax):" }), _jsxs("span", { children: [formatNumber(itemsTotalTaxIncl), " ", state.currency] })] })] }) }) }) }), state.status === "PAYMENTSCHEDULED" && (_jsx("div", { className: "mt-8", children: !isFiatCurrency(state.currency) ? (_jsx(InvoiceToGnosis, { docState: state })) : (_jsx(RequestFinance, { docState: state })) }))] }));
|
|
365
|
+
}, onUpdateItem: (item) => dispatch(actions.editLineItem(item)), dispatch: dispatch, paymentAccounts: state.paymentAccounts || [] }) }), _jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6", children: _jsx("div", { className: "md:col-start-2", children: _jsx("div", { className: "rounded-lg border border-gray-200 bg-gray-50 p-6 shadow-sm", children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex justify-between text-gray-700", children: [_jsx("span", { className: "font-medium", children: "Subtotal (excl. tax):" }), _jsxs("span", { children: [formatNumber(itemsTotalTaxExcl), " ", state.currency] })] }), _jsxs("div", { className: "flex justify-between border-t border-gray-200 pt-4 text-lg font-bold text-gray-900", children: [_jsx("span", { children: "Total (incl. tax):" }), _jsxs("span", { children: [formatNumber(itemsTotalTaxIncl), " ", state.currency] })] })] }) }) }) }), state.status === "PAYMENTSCHEDULED" && (_jsx("div", { className: "mt-8", children: !isFiatCurrency(state.currency) ? (_jsx(InvoiceToGnosis, { docState: state })) : (_jsx(RequestFinance, { docState: state })) }))] }));
|
|
377
366
|
}
|
|
@@ -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 !== 'http://localhost:3000/') {
|
|
9
|
-
GRAPHQL_URL = 'https://switchboard.powerhouse.xyz/graphql/invoice';
|
|
9
|
+
GRAPHQL_URL = 'https://switchboard-dev.powerhouse.xyz/graphql/invoice';
|
|
10
10
|
}
|
|
11
11
|
export async function loadPDFFile({ file, dispatch, }) {
|
|
12
12
|
if (!file)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invoiceToGnosis.d.ts","sourceRoot":"","sources":["../../../editors/invoice/invoiceToGnosis.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAQxC,UAAU,oBAAoB;IAC5B,QAAQ,EAAE,GAAG,CAAC;CACf;AAED,QAAA,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,
|
|
1
|
+
{"version":3,"file":"invoiceToGnosis.d.ts","sourceRoot":"","sources":["../../../editors/invoice/invoiceToGnosis.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAQxC,UAAU,oBAAoB;IAC5B,QAAQ,EAAE,GAAG,CAAC;CACf;AAED,QAAA,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAwKnD,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState } from "react";
|
|
3
3
|
let GRAPHQL_URL = "http://localhost:4001/graphql/invoice";
|
|
4
4
|
if (window.document.baseURI !== "http://localhost:3000/") {
|
|
5
|
-
GRAPHQL_URL = "https://switchboard.powerhouse.xyz/graphql/invoice";
|
|
5
|
+
GRAPHQL_URL = "https://switchboard-dev.powerhouse.xyz/graphql/invoice";
|
|
6
6
|
}
|
|
7
7
|
const InvoiceToGnosis = ({ docState }) => {
|
|
8
8
|
const [isLoading, setIsLoading] = useState(false);
|
|
@@ -33,27 +33,6 @@ const InvoiceToGnosis = ({ docState }) => {
|
|
|
33
33
|
},
|
|
34
34
|
// Add more networks as needed
|
|
35
35
|
};
|
|
36
|
-
// Separate payerWallet configuration
|
|
37
|
-
const payerWallet = {
|
|
38
|
-
BASE: {
|
|
39
|
-
rpc: "https://base.llamarpc.com",
|
|
40
|
-
chainName: "Base",
|
|
41
|
-
chainId: "8453",
|
|
42
|
-
address: "0x1FB6bEF04230d67aF0e3455B997a28AFcCe1F45e", // Safe address
|
|
43
|
-
},
|
|
44
|
-
ETHEREUM: {
|
|
45
|
-
rpc: "https://eth.llamarpc.com",
|
|
46
|
-
chainName: "Ethereum",
|
|
47
|
-
chainId: "1",
|
|
48
|
-
address: "0x1FB6bEF04230d67aF0e3455B997a28AFcCe1F45e", // Safe address
|
|
49
|
-
},
|
|
50
|
-
"ARBITRUM ONE": {
|
|
51
|
-
rpc: "https://arb1.arbitrum.io/rpc",
|
|
52
|
-
chainName: "Arbitrum One",
|
|
53
|
-
chainId: "42161",
|
|
54
|
-
address: "0x1FB6bEF04230d67aF0e3455B997a28AFcCe1F45e", // Safe address
|
|
55
|
-
},
|
|
56
|
-
};
|
|
57
36
|
// Extract payment details from current-state.json
|
|
58
37
|
const paymentDetails = {
|
|
59
38
|
payeeWallet: {
|
|
@@ -91,8 +70,8 @@ const InvoiceToGnosis = ({ docState }) => {
|
|
|
91
70
|
},
|
|
92
71
|
body: JSON.stringify({
|
|
93
72
|
query: `
|
|
94
|
-
mutation Invoice_processGnosisPayment($
|
|
95
|
-
Invoice_processGnosisPayment(
|
|
73
|
+
mutation Invoice_processGnosisPayment($chainName: String!, $paymentDetails: JSON!, $invoiceNo: String!) {
|
|
74
|
+
Invoice_processGnosisPayment(chainName: $chainName, paymentDetails: $paymentDetails, invoiceNo: $invoiceNo) {
|
|
96
75
|
success
|
|
97
76
|
data
|
|
98
77
|
error
|
|
@@ -100,7 +79,7 @@ const InvoiceToGnosis = ({ docState }) => {
|
|
|
100
79
|
}
|
|
101
80
|
`,
|
|
102
81
|
variables: {
|
|
103
|
-
|
|
82
|
+
chainName: chainName,
|
|
104
83
|
paymentDetails: paymentDetails,
|
|
105
84
|
invoiceNo: docState.invoiceNo,
|
|
106
85
|
},
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Dispatch } from "react";
|
|
2
|
+
import { InvoiceLineItemTag } from "../../../document-models/invoice/index.js";
|
|
3
|
+
interface TagAssignmentRow {
|
|
4
|
+
id: string;
|
|
5
|
+
item: string;
|
|
6
|
+
period: string;
|
|
7
|
+
expenseAccount: string;
|
|
8
|
+
total: string;
|
|
9
|
+
lineItemTag: InvoiceLineItemTag[];
|
|
10
|
+
}
|
|
11
|
+
interface LineItemTagsTableProps {
|
|
12
|
+
lineItems: TagAssignmentRow[];
|
|
13
|
+
onSave: (updatedLineItems: TagAssignmentRow[], paymentAccount: string) => void;
|
|
14
|
+
onClose: () => void;
|
|
15
|
+
dispatch: Dispatch<any>;
|
|
16
|
+
paymentAccounts: string[];
|
|
17
|
+
}
|
|
18
|
+
export declare function LineItemTagsTable({ lineItems, onSave, onClose, dispatch, paymentAccounts, }: LineItemTagsTableProps): import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=lineItemTags.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lineItemTags.d.ts","sourceRoot":"","sources":["../../../../editors/invoice/lineItemTags/lineItemTags.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,QAAQ,EAAY,MAAM,OAAO,CAAC;AAKlD,OAAO,EAAW,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;AAExF,UAAU,gBAAgB;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,kBAAkB,EAAE,CAAC;CACnC;AAED,UAAU,sBAAsB;IAC9B,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,MAAM,EAAE,CACN,gBAAgB,EAAE,gBAAgB,EAAE,EACpC,cAAc,EAAE,MAAM,KACnB,IAAI,CAAC;IACV,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC;IACxB,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,wBAAgB,iBAAiB,CAAC,EAChC,SAAS,EACT,MAAM,EACN,OAAO,EACP,QAAQ,EACR,eAAe,GAChB,EAAE,sBAAsB,2CAuKxB"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { X, Tag } from "lucide-react";
|
|
4
|
+
import { Button } from "@powerhousedao/design-system";
|
|
5
|
+
import { Select } from "@powerhousedao/document-engineering/ui";
|
|
6
|
+
import { expenseAccountOptions } from "./tagMapping.js";
|
|
7
|
+
import { actions } from "../../../document-models/invoice/index.js";
|
|
8
|
+
export function LineItemTagsTable({ lineItems, onSave, onClose, dispatch, paymentAccounts, }) {
|
|
9
|
+
const [taggedItems, setTaggedItems] = useState(lineItems);
|
|
10
|
+
const [paymentAccount, setPaymentAccount] = useState("Powerhouse USD");
|
|
11
|
+
const periodOptions = [
|
|
12
|
+
"Jan 2025",
|
|
13
|
+
"Feb 2025",
|
|
14
|
+
"Mar 2025",
|
|
15
|
+
"Apr 2025",
|
|
16
|
+
"May 2025",
|
|
17
|
+
"Jun 2025",
|
|
18
|
+
];
|
|
19
|
+
const handleSave = () => {
|
|
20
|
+
onSave(taggedItems, paymentAccount);
|
|
21
|
+
onClose();
|
|
22
|
+
};
|
|
23
|
+
const handleBackdropClick = (e) => {
|
|
24
|
+
if (e.target === e.currentTarget) {
|
|
25
|
+
onClose();
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
return (_jsxs("div", { className: "w-full", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-gray-200 p-6 bg-white z-10", children: [_jsxs("span", { className: "flex items-center gap-2", children: [_jsx("h2", { className: "text-2xl font-semibold text-gray-900", children: "Assign Tags " }), _jsx(Tag, { style: { width: 28, height: 28, color: "white", fill: "#475264" } })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs(Button, { color: "light", size: "medium", children: ["Reset", " "] }), _jsx("button", { onClick: onClose, className: "rounded-full p-2 hover:bg-gray-100", children: _jsx(X, { size: 24, className: "text-gray-500" }) })] })] }), _jsx("div", { className: "overflow-x-auto rounded-lg border border-gray-200", children: _jsxs("table", { className: "w-full border-collapse bg-white", children: [_jsx("thead", { className: "bg-gray-50 z-10", children: _jsxs("tr", { children: [_jsx("th", { className: "border-b border-gray-200 p-3 text-left", children: "Item" }), _jsx("th", { className: "border-b border-gray-200 p-3 text-left", children: "Period" }), _jsx("th", { className: "border-b border-gray-200 p-3 text-left", children: "Xero Expense Account" }), _jsx("th", { className: "border-b border-gray-200 p-3 text-right", children: "Total" })] }) }), _jsx("tbody", { children: taggedItems.map((item) => (_jsxs("tr", { className: "hover:bg-gray-50", children: [_jsx("td", { className: "border-b border-gray-200 p-3", children: _jsx("input", { type: "text", value: item.item, onChange: (e) => setTaggedItems((prev) => prev.map((row) => row.id === item.id
|
|
29
|
+
? { ...row, item: e.target.value }
|
|
30
|
+
: row)), className: "w-full rounded border border-gray-300 px-3 py-2 focus:border-blue-500 focus:outline-none" }) }), _jsx("td", { className: "border-b border-gray-200 p-3", children: _jsxs("select", { value: item.period, onChange: (e) => setTaggedItems((prev) => prev.map((row) => row.id === item.id
|
|
31
|
+
? { ...row, period: e.target.value }
|
|
32
|
+
: row)), className: "w-full rounded border border-gray-300 px-3 py-2 focus:border-blue-500 focus:outline-none", children: [_jsx("option", { value: "", children: "Select Period" }), periodOptions.map((period) => (_jsx("option", { value: period, children: period }, period)))] }) }), _jsx("td", { className: "border-b border-gray-200 p-3", children: _jsx(Select, { options: expenseAccountOptions, value: item.lineItemTag.find((tag) => tag.dimension === "xero-expense-account")?.value || "", placeholder: "Select Expense Account", searchable: true, onChange: (value) => {
|
|
33
|
+
dispatch(actions.setLineItemTag({
|
|
34
|
+
lineItemId: item.id,
|
|
35
|
+
dimension: "xero-expense-account",
|
|
36
|
+
value: value,
|
|
37
|
+
label: expenseAccountOptions.find((option) => option.value === value)?.label,
|
|
38
|
+
}));
|
|
39
|
+
} }) }), _jsx("td", { className: "border-b border-gray-200 p-3 text-right font-medium", children: item.total })] }, item.id))) })] }) }), _jsx("div", { className: "border-t border-gray-200 p-6", children: _jsxs("div", { className: "flex items-center justify-end gap-4", children: [_jsx("label", { className: "text-lg font-medium text-gray-900", children: "Payment Account" }), _jsx(Select, { options: [
|
|
40
|
+
{ label: "Powerhouse USD", value: "Powerhouse USD" },
|
|
41
|
+
{ label: "Powerhouse EUR", value: "Powerhouse EUR" },
|
|
42
|
+
], value: paymentAccounts && paymentAccounts.length > 0
|
|
43
|
+
? paymentAccounts[0]
|
|
44
|
+
: "", placeholder: "Select Payment Account", searchable: true, onChange: (value) => {
|
|
45
|
+
dispatch(actions.addPaymentAccount({ paymentAccount: value }));
|
|
46
|
+
} })] }) }), _jsx("div", { className: "border-t border-gray-200 p-6", children: _jsx("div", { className: "flex justify-end", children: _jsx("button", { onClick: handleSave, className: "rounded bg-blue-600 px-4 py-2 text-white hover:bg-blue-700", children: "Save Tags" }) }) })] }));
|
|
47
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tagMapping.d.ts","sourceRoot":"","sources":["../../../../editors/invoice/lineItemTags/tagMapping.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAC;AAEtE,eAAO,MAAM,qBAAqB,EAAE,YAAY,EA6D/C,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export const expenseAccountOptions = [
|
|
2
|
+
{ label: "Grants from Maker DAO", value: "200" },
|
|
3
|
+
{ label: "Request Finance IC account", value: "2222" },
|
|
4
|
+
{ label: "Interest Income", value: "270" },
|
|
5
|
+
{ label: "Activities and Events", value: "3000" },
|
|
6
|
+
{ label: "Meals", value: "3001" },
|
|
7
|
+
{ label: "Airfare", value: "3002" },
|
|
8
|
+
{ label: "Hotels", value: "3003" },
|
|
9
|
+
{ label: "Transportation (Uber, Taxi etc)", value: "3004" },
|
|
10
|
+
{ label: "Cost of Goods Sold", value: "310" },
|
|
11
|
+
{ label: "Advertising", value: "400" },
|
|
12
|
+
{ label: "Legal Fees Abroad", value: "4001" },
|
|
13
|
+
{ label: "Legal Fees Switzerland", value: "4002" },
|
|
14
|
+
{ label: "Finance Team Fees Abroad", value: "4003" },
|
|
15
|
+
{ label: "Fnance and Accounting Fees Switzerland", value: "4004" },
|
|
16
|
+
{ label: "Software Development Team Fees", value: "4005" },
|
|
17
|
+
{ label: "Research Team Fees", value: "4006" },
|
|
18
|
+
{ label: "Marketing Team Fees", value: "4007" },
|
|
19
|
+
{ label: "Health Care Fees", value: "4008" },
|
|
20
|
+
{ label: "Contractor Fees", value: "4009" },
|
|
21
|
+
{ label: "Insurance Fees Team", value: "4010" },
|
|
22
|
+
{ label: "HR Fees", value: "4011" },
|
|
23
|
+
{ label: "Team Bonus", value: "4012" },
|
|
24
|
+
{ label: "Refferal Fees", value: "4013" },
|
|
25
|
+
{ label: "Depreciation", value: "416" },
|
|
26
|
+
{ label: "Freight & Courier", value: "425" },
|
|
27
|
+
{ label: "Interest Expense", value: "437" },
|
|
28
|
+
{ label: "Office Expenses", value: "453" },
|
|
29
|
+
{ label: "Rent", value: "469" },
|
|
30
|
+
{ label: "Subscriptions", value: "485" },
|
|
31
|
+
{ label: "Bank Revaluations", value: "497" },
|
|
32
|
+
{ label: "Unrealised Currency Gains", value: "498" },
|
|
33
|
+
{ label: "Realised Currency Gains", value: "499" },
|
|
34
|
+
{ label: "Income Tax Expense", value: "505" },
|
|
35
|
+
{ label: "Accounts Receivable", value: "610" },
|
|
36
|
+
{ label: "Prepayments", value: "620" },
|
|
37
|
+
{ label: "Inventory", value: "630" },
|
|
38
|
+
{ label: "Software/IT Subscriptions", value: "701" },
|
|
39
|
+
{ label: "Office Equipment", value: "710" },
|
|
40
|
+
{ label: "Less Accumulated Depreciation on Office Equipment", value: "711" },
|
|
41
|
+
{ label: "Computer Equipment", value: "720" },
|
|
42
|
+
{ label: "Less Accumulated Depreciation on Computer Equipment", value: "721" },
|
|
43
|
+
{ label: "Accounts Payable", value: "800" },
|
|
44
|
+
{ label: "Bank Fees", value: "8000" },
|
|
45
|
+
{ label: "Gas Fees", value: "8001" },
|
|
46
|
+
{ label: "Exchange Fees", value: "8003" },
|
|
47
|
+
{ label: "Unpaid Expense Claims", value: "801" },
|
|
48
|
+
{ label: "Wages Payable", value: "803" },
|
|
49
|
+
{ label: "Sales Tax", value: "820" },
|
|
50
|
+
{ label: "Employee Tax Payable", value: "825" },
|
|
51
|
+
{ label: "Superannuation Payable", value: "826" },
|
|
52
|
+
{ label: "Income Tax Payable", value: "830" },
|
|
53
|
+
{ label: "Historical Adjustment", value: "840" },
|
|
54
|
+
{ label: "Suspense", value: "850" },
|
|
55
|
+
{ label: "Rounding", value: "860" },
|
|
56
|
+
{ label: "Tracking Transfers", value: "877" },
|
|
57
|
+
{ label: "Owner A Drawings", value: "880" },
|
|
58
|
+
{ label: "Owner A Funds Introduced", value: "881" },
|
|
59
|
+
{ label: "Loan", value: "900" },
|
|
60
|
+
{ label: "Retained Earnings", value: "960" },
|
|
61
|
+
{ label: "Owner A Share Capital", value: "970" }
|
|
62
|
+
];
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { EditInvoiceInput, DeleteLineItemInput } from "../../document-models/invoice/index.js";
|
|
1
|
+
import { EditInvoiceInput, DeleteLineItemInput, InvoiceLineItemTag } from "../../document-models/invoice/index.js";
|
|
2
|
+
import { Dispatch } from "react";
|
|
3
|
+
export declare function formatNumber(value: number): string;
|
|
2
4
|
type LineItem = {
|
|
3
5
|
currency: string;
|
|
4
6
|
description: string;
|
|
@@ -9,6 +11,7 @@ type LineItem = {
|
|
|
9
11
|
totalPriceTaxIncl: number;
|
|
10
12
|
unitPriceTaxExcl: number;
|
|
11
13
|
unitPriceTaxIncl: number;
|
|
14
|
+
lineItemTag: InvoiceLineItemTag[];
|
|
12
15
|
};
|
|
13
16
|
type LineItemsTableProps = {
|
|
14
17
|
readonly lineItems: LineItem[];
|
|
@@ -17,7 +20,9 @@ type LineItemsTableProps = {
|
|
|
17
20
|
readonly onUpdateItem: (item: LineItem) => void;
|
|
18
21
|
readonly onDeleteItem: (input: DeleteLineItemInput) => void;
|
|
19
22
|
readonly onUpdateCurrency: (input: EditInvoiceInput) => void;
|
|
23
|
+
readonly dispatch: Dispatch<any>;
|
|
24
|
+
readonly paymentAccounts: string[];
|
|
20
25
|
};
|
|
21
|
-
export declare function LineItemsTable({ lineItems, currency, onAddItem, onUpdateItem, onDeleteItem, onUpdateCurrency, }: LineItemsTableProps): import("react/jsx-runtime").JSX.Element;
|
|
26
|
+
export declare function LineItemsTable({ lineItems, currency, onAddItem, onUpdateItem, onDeleteItem, onUpdateCurrency, dispatch, paymentAccounts }: LineItemsTableProps): import("react/jsx-runtime").JSX.Element;
|
|
22
27
|
export {};
|
|
23
28
|
//# sourceMappingURL=lineItems.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lineItems.d.ts","sourceRoot":"","sources":["../../../editors/invoice/lineItems.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAC;
|
|
1
|
+
{"version":3,"file":"lineItems.d.ts","sourceRoot":"","sources":["../../../editors/invoice/lineItems.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AACnH,OAAO,EAA0D,QAAQ,EAAE,MAAM,OAAO,CAAC;AAqBzF,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAsBlD;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,kBAAkB,EAAE,CAAC;CACnC,CAAC;AAoNF,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,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC;IACjC,QAAQ,CAAC,eAAe,EAAE,MAAM,EAAE,CAAC;CACpC,CAAC;AAEF,wBAAgB,cAAc,CAAC,EAC7B,SAAS,EACT,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,QAAQ,EACR,eAAe,EAChB,EAAE,mBAAmB,2CAuKrB"}
|
|
@@ -3,28 +3,35 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
/* eslint-disable react/jsx-no-bind */
|
|
4
4
|
/* eslint-disable react/button-has-type */
|
|
5
5
|
import { RWAButton } from "@powerhousedao/design-system";
|
|
6
|
-
import { forwardRef, useState, useMemo } from "react";
|
|
6
|
+
import { forwardRef, useState, useMemo, useRef } from "react";
|
|
7
7
|
import { v4 as uuidv4 } from "uuid";
|
|
8
|
+
import { Tag } from "lucide-react";
|
|
8
9
|
import { NumberForm } from "./components/numberForm.js";
|
|
9
10
|
import { InputField } from "./components/inputField.js";
|
|
11
|
+
import { LineItemTagsTable } from "./lineItemTags/lineItemTags.js";
|
|
10
12
|
// Helper function to get precision based on currency
|
|
11
13
|
function getCurrencyPrecision(currency) {
|
|
12
14
|
return currency === "USDS" || currency === "DAI" ? 6 : 2;
|
|
13
15
|
}
|
|
14
|
-
|
|
15
|
-
function formatNumber(value) {
|
|
16
|
+
export function formatNumber(value) {
|
|
16
17
|
// Check if the value has decimal places
|
|
17
18
|
const hasDecimals = value % 1 !== 0;
|
|
18
19
|
// If no decimals or only trailing zeros after 2 decimal places, show 2 decimal places
|
|
19
20
|
if (!hasDecimals || value.toFixed(5).endsWith("000")) {
|
|
20
|
-
return value.
|
|
21
|
+
return value.toLocaleString('en-US', {
|
|
22
|
+
minimumFractionDigits: 2,
|
|
23
|
+
maximumFractionDigits: 2
|
|
24
|
+
});
|
|
21
25
|
}
|
|
22
|
-
// Otherwise, show
|
|
26
|
+
// Otherwise, show actual decimal places up to 5
|
|
23
27
|
const stringValue = value.toString();
|
|
24
28
|
const decimalPart = stringValue.split(".")[1] || "";
|
|
25
29
|
// Determine how many decimal places to show (up to 5)
|
|
26
30
|
const decimalPlaces = Math.min(Math.max(2, decimalPart.length), 5);
|
|
27
|
-
return value.
|
|
31
|
+
return value.toLocaleString('en-US', {
|
|
32
|
+
minimumFractionDigits: decimalPlaces,
|
|
33
|
+
maximumFractionDigits: decimalPlaces
|
|
34
|
+
});
|
|
28
35
|
}
|
|
29
36
|
const EditableLineItem = forwardRef(function EditableLineItem(props, ref) {
|
|
30
37
|
const { item, onSave, onCancel, currency } = props;
|
|
@@ -128,16 +135,22 @@ const EditableLineItem = forwardRef(function EditableLineItem(props, ref) {
|
|
|
128
135
|
unitPriceTaxIncl: calculatedValues.unitPriceTaxIncl,
|
|
129
136
|
totalPriceTaxExcl: calculatedValues.totalPriceTaxExcl,
|
|
130
137
|
totalPriceTaxIncl: calculatedValues.totalPriceTaxIncl,
|
|
138
|
+
lineItemTag: [],
|
|
131
139
|
};
|
|
132
140
|
onSave(completeItem);
|
|
133
141
|
}
|
|
134
|
-
return (_jsxs("tr", { ref: ref, className: "hover:bg-gray-50", children: [_jsx("td", { className: "border border-gray-200 p-3", children: _jsx(InputField, { onBlur: () => { }, handleInputChange: (e) => {
|
|
142
|
+
return (_jsxs("tr", { ref: ref, className: "hover:bg-gray-50", children: [_jsx("td", { className: "border border-gray-200 p-3", style: { width: '38%' }, children: _jsx(InputField, { onBlur: () => { }, handleInputChange: (e) => {
|
|
135
143
|
setEditedItem((prev) => ({ ...prev, description: e.target.value }));
|
|
136
|
-
}, value: editedItem.description ?? "", placeholder: "Description" }) }), _jsx("td", { className: "border border-gray-200 p-3", children: _jsx(NumberForm, { number: editedItem.quantity ?? "", precision: 0, handleInputChange: handleInputChange("quantity"), placeholder: "Quantity" }) }), _jsx("td", { className: "border border-gray-200 p-3", children: _jsx(NumberForm, { number: editedItem.unitPriceTaxExcl ?? "", precision: getCurrencyPrecision(currency), handleInputChange: handleInputChange("unitPriceTaxExcl"), placeholder: "Unit Price (excl. tax)" }) }), _jsx("td", { className: "border border-gray-200 p-3", children: _jsx(NumberForm, { number: editedItem.taxPercent ?? "", precision: 0, min: 0, max: 100, handleInputChange: handleInputChange("taxPercent"), placeholder: "Tax %" }) }), _jsx("td", { className: "border border-gray-200 p-3 text-right font-medium", children: formatNumber(calculatedValues.totalPriceTaxExcl) }), _jsx("td", { className: "border border-gray-200 p-3 text-right font-medium", children: formatNumber(calculatedValues.totalPriceTaxIncl) }), _jsx("td", { className: "border border-gray-200 p-3", children: _jsxs("div", { className: "flex space-x-2", children: [_jsx("button", { style: { backgroundColor: "blue" }, className: "rounded bg-blue-600 px-3 py-1 text-white hover:bg-blue-700", onClick: handleSave, children: "Save" }), _jsx("button", { className: "rounded bg-gray-500 px-3 py-1 text-white hover:bg-gray-600", onClick: onCancel, children: "Cancel" })] }) })] }));
|
|
144
|
+
}, value: editedItem.description ?? "", placeholder: "Description" }) }), _jsx("td", { className: "border border-gray-200 p-3", style: { width: '8%' }, children: _jsx(NumberForm, { number: editedItem.quantity ?? "", precision: 0, handleInputChange: handleInputChange("quantity"), placeholder: "Quantity" }) }), _jsx("td", { className: "border border-gray-200 p-3", style: { width: '16%' }, children: _jsx(NumberForm, { number: editedItem.unitPriceTaxExcl ?? "", precision: getCurrencyPrecision(currency), handleInputChange: handleInputChange("unitPriceTaxExcl"), placeholder: "Unit Price (excl. tax)" }) }), _jsx("td", { className: "border border-gray-200 p-3", style: { width: '8%' }, children: _jsx(NumberForm, { number: editedItem.taxPercent ?? "", precision: 0, min: 0, max: 100, handleInputChange: handleInputChange("taxPercent"), placeholder: "Tax %" }) }), _jsx("td", { className: "border border-gray-200 p-3 text-right font-medium", style: { width: '14%' }, children: formatNumber(calculatedValues.totalPriceTaxExcl) }), _jsx("td", { className: "border border-gray-200 p-3 text-right font-medium", style: { width: '14%' }, children: formatNumber(calculatedValues.totalPriceTaxIncl) }), _jsx("td", { className: "border border-gray-200 p-3", children: _jsxs("div", { className: "flex space-x-2", children: [_jsx("button", { style: { backgroundColor: "blue" }, className: "rounded bg-blue-600 px-3 py-1 text-white hover:bg-blue-700", onClick: handleSave, children: "Save" }), _jsx("button", { className: "rounded bg-gray-500 px-3 py-1 text-white hover:bg-gray-600", onClick: onCancel, children: "Cancel" })] }) })] }));
|
|
137
145
|
});
|
|
138
|
-
export function LineItemsTable({ lineItems, currency, onAddItem, onUpdateItem, onDeleteItem, onUpdateCurrency, }) {
|
|
146
|
+
export function LineItemsTable({ lineItems, currency, onAddItem, onUpdateItem, onDeleteItem, onUpdateCurrency, dispatch, paymentAccounts }) {
|
|
139
147
|
const [editingId, setEditingId] = useState(null);
|
|
140
148
|
const [isAddingNew, setIsAddingNew] = useState(false);
|
|
149
|
+
const [showTagTable, setShowTagTable] = useState(false);
|
|
150
|
+
const containerRef = useRef(null);
|
|
151
|
+
const tableContainerRef = useRef(null);
|
|
152
|
+
const tableRef = useRef(null);
|
|
153
|
+
const [modalRect, setModalRect] = useState(null);
|
|
141
154
|
function handleAddClick() {
|
|
142
155
|
setIsAddingNew(true);
|
|
143
156
|
}
|
|
@@ -148,10 +161,26 @@ export function LineItemsTable({ lineItems, currency, onAddItem, onUpdateItem, o
|
|
|
148
161
|
function handleCancelNewItem() {
|
|
149
162
|
setIsAddingNew(false);
|
|
150
163
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
164
|
+
// Transform line items to TagAssignmentRow format for the tag table
|
|
165
|
+
const tagAssignmentRows = lineItems.map(item => ({
|
|
166
|
+
id: item.id,
|
|
167
|
+
item: item.description,
|
|
168
|
+
period: 'Jan 2025', // Default value
|
|
169
|
+
expenseAccount: '', // Default value
|
|
170
|
+
total: `$${formatNumber(item.totalPriceTaxIncl)}`,
|
|
171
|
+
lineItemTag: item.lineItemTag,
|
|
172
|
+
}));
|
|
173
|
+
const handleTagsSave = (updatedTaggedItems, paymentAccount) => {
|
|
174
|
+
// Handle the saved tags here if needed
|
|
175
|
+
setShowTagTable(false);
|
|
176
|
+
};
|
|
177
|
+
if (showTagTable) {
|
|
178
|
+
return (_jsx(LineItemTagsTable, { lineItems: tagAssignmentRows, onSave: handleTagsSave, onClose: () => setShowTagTable(false), dispatch: dispatch, paymentAccounts: paymentAccounts }));
|
|
179
|
+
}
|
|
180
|
+
return (_jsx("div", { ref: containerRef, className: "relative w-full", children: _jsxs("div", { className: "mt-4", children: [_jsxs("div", { className: "mb-4 flex items-center justify-between", children: [_jsx("div", { className: "flex items-center gap-4", children: _jsx("h4", { className: "text-xl font-semibold text-gray-900", children: "Line Items" }) }), _jsx(RWAButton, { className: "mb-2", disabled: isAddingNew, onClick: handleAddClick, children: "Add Line Item" })] }), _jsx("div", { ref: tableContainerRef, className: "overflow-x-auto rounded-lg border border-gray-200", children: _jsxs("table", { ref: tableRef, className: "w-full table-fixed border-collapse bg-white", children: [_jsx("thead", { children: _jsxs("tr", { className: "bg-gray-50", children: [_jsx("th", { className: "border-b border-gray-200 p-3 text-left", style: { width: '38%' }, children: "Description" }), _jsx("th", { className: "border-b border-gray-200 p-3 text-right", style: { width: '8%' }, children: "Quantity" }), _jsx("th", { className: "border-b border-gray-200 p-3 text-right", style: { width: '16%' }, children: "Unit Price (excl. tax)" }), _jsx("th", { className: "border-b border-gray-200 p-3 text-right", style: { width: '8%' }, children: "Tax %" }), _jsx("th", { className: "border-b border-gray-200 p-3 text-right", style: { width: '14%' }, children: "Total (excl. tax)" }), _jsx("th", { className: "border-b border-gray-200 p-3 text-right", style: { width: '14%' }, children: "Total (incl. tax)" }), _jsx("th", { className: "border-b border-gray-200 p-3 text-center", children: _jsxs("span", { className: "flex items-center justify-center gap-2", children: [_jsx("span", { className: "text-sm", children: "Actions" }), _jsx(Tag, { onClick: () => setShowTagTable(true), style: { cursor: "pointer", width: 28, height: 28, color: "white", fill: "#475264" } })] }) })] }) }), _jsxs("tbody", { children: [lineItems.map((item) => editingId === item.id ? (_jsx(EditableLineItem, { currency: currency, item: item, onCancel: () => setEditingId(null), onSave: (updatedItem) => {
|
|
181
|
+
onUpdateItem(updatedItem);
|
|
182
|
+
setEditingId(null);
|
|
183
|
+
} }, item.id)) : (_jsxs("tr", { className: "hover:bg-gray-50", children: [_jsx("td", { className: "border-b border-gray-200 p-3", children: item.description }), _jsx("td", { className: "border-b border-gray-200 p-3 text-right", children: item.quantity }), _jsx("td", { className: "border-b border-gray-200 p-3 text-right", children: formatNumber(item.unitPriceTaxExcl) }), _jsxs("td", { className: "border-b border-gray-200 p-3 text-right", children: [typeof item.taxPercent === "number"
|
|
184
|
+
? Math.round(item.taxPercent)
|
|
185
|
+
: 0, "%"] }), _jsx("td", { className: "border-b border-gray-200 p-3 text-right font-medium", children: formatNumber(item.totalPriceTaxExcl) }), _jsx("td", { className: "border-b border-gray-200 p-3 text-right font-medium", children: formatNumber(item.totalPriceTaxIncl) }), _jsx("td", { className: "border-b border-gray-200 p-3", children: _jsxs("div", { className: "flex justify-center space-x-2", children: [_jsx("button", { style: { backgroundColor: "lightblue" }, className: "rounded bg-blue-600 px-3 py-1 text-white hover:bg-blue-700", 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 })) : null] })] }) })] }) }));
|
|
157
186
|
}
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState } from "react";
|
|
3
3
|
let GRAPHQL_URL = 'http://localhost:4001/graphql/invoice';
|
|
4
4
|
if (window.document.baseURI !== 'http://localhost:3000/') {
|
|
5
|
-
GRAPHQL_URL = 'https://switchboard.powerhouse.xyz/graphql/invoice';
|
|
5
|
+
GRAPHQL_URL = 'https://switchboard-dev.powerhouse.xyz/graphql/invoice';
|
|
6
6
|
}
|
|
7
7
|
const RequestFinance = ({ docState }) => {
|
|
8
8
|
const [isLoading, setIsLoading] = useState(false);
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
let GRAPHQL_URL = 'http://localhost:4001/graphql/invoice';
|
|
9
9
|
if (window.document.baseURI !== 'http://localhost:3000/') {
|
|
10
|
-
GRAPHQL_URL = 'https://switchboard.powerhouse.xyz/graphql/invoice';
|
|
10
|
+
GRAPHQL_URL = 'https://switchboard-dev.powerhouse.xyz/graphql/invoice';
|
|
11
11
|
}
|
|
12
12
|
export async function uploadPdfChunked(pdfData, endpoint = GRAPHQL_URL, chunkSize = 500 * 1024, // 500KB chunks
|
|
13
13
|
onProgress) {
|
|
@@ -33,7 +33,7 @@ async function testBatchTransfer() {
|
|
|
33
33
|
amount: '15.5',
|
|
34
34
|
},
|
|
35
35
|
];
|
|
36
|
-
const result = await executeTransferProposal(payerWallet, paymentDetails);
|
|
36
|
+
const result = await executeTransferProposal(payerWallet.chainName, paymentDetails);
|
|
37
37
|
console.log('\n✅ Batch transaction proposed successfully:');
|
|
38
38
|
console.log(result);
|
|
39
39
|
}
|
|
@@ -23,6 +23,6 @@ export interface TransferResult {
|
|
|
23
23
|
safeAddress: string;
|
|
24
24
|
paymentDetails: PaymentDetail[];
|
|
25
25
|
}
|
|
26
|
-
declare function executeTransferProposal(
|
|
26
|
+
declare function executeTransferProposal(chainName: string, paymentDetailsInput: PaymentDetail | PaymentDetail[]): Promise<TransferResult>;
|
|
27
27
|
export { executeTransferProposal };
|
|
28
28
|
//# sourceMappingURL=gnosisTransactionBuilder.d.ts.map
|