Compare commits

...

29 Commits

Author SHA1 Message Date
a.bouhuolia
da699a766a Merge branch 'develop' into main 2022-01-13 15:40:55 +02:00
a.bouhuolia
a958c6088a chore: dump version. 2022-01-13 15:35:40 +02:00
a.bouhuolia
572d59577c chore: dump version changlogs. 2022-01-13 15:34:54 +02:00
Ahmed Bouhuolia
21ae8aabfc Merge pull request #22 from bigcapitalhq/BIG-261-hide-convert-to-invoice-button-on-the-context-menu-if-already-converted
fix: `BIG-261` Hide convert to invoice button on the context menu if invoice already converted.
2022-01-13 15:18:49 +02:00
a.bouhuolia
8f267b98e4 fix(ContactBalanceSummary): BIG-288 percentage of column. 2022-01-12 20:15:00 +02:00
a.bouhuolia
dcfe92076b Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2022-01-11 18:10:23 +02:00
a.bouhuolia
79cb7f1a1d fix(PaymentReceive): depend on loading state instead fetching. 2022-01-11 18:10:17 +02:00
a.bouhuolia
1380e288e0 fix(BalanceSheet): BIG-281 report alerts re-positioning. 2022-01-11 18:09:12 +02:00
Ahmed Bouhuolia
b055908e12 Merge pull request #19 from bigcapitalhq/BIG-274-duplicated-description-in-payment-receive-details
`BIG-274` Duplicated description in payment receive details.
2022-01-11 17:29:19 +02:00
Ahmed Bouhuolia
20c140474b Merge pull request #20 from bigcapitalhq/BIG-277-separate-customer-and-vendor-activate-inactivate-alerts
BIG-277 Separate customer and vendor.
2022-01-11 17:28:47 +02:00
Ahmed Bouhuolia
9ee5eba92b Merge branch 'develop' into BIG-277-separate-customer-and-vendor-activate-inactivate-alerts 2022-01-11 17:28:30 +02:00
Ahmed Bouhuolia
e755a2a318 Merge pull request #21 from bigcapitalhq/BIG-263-optimize-sales-print-templates
`Big 263` optimize sales print templates
2022-01-11 17:25:44 +02:00
elforjani13
1656691940 feat(PaymentReceivePdf): payment pdf preview. 2022-01-11 14:34:41 +02:00
elforjani13
dd7d11ffb7 feat(CreditNotePdf): credit note pdf preview. 2022-01-11 14:33:51 +02:00
elforjani13
5c847be420 BIG-277 Separate customer and vendor. 2022-01-09 21:18:45 +02:00
a.bouhuolia
da3193195c fix: BIG-274 Duplicated description in payment receive details. 2022-01-09 21:12:54 +02:00
a.bouhuolia
e3141250b6 fix: BIG-261 Hide convert to invoice button on the context menu if already converted. 2022-01-09 13:07:32 +02:00
a.bouhuolia
f1899e1ce1 Merge branch 'develop' into main 2022-01-08 18:20:08 +02:00
elforjani13
76d6cd0eaa fix(MoneyOutForm): BIG-270 publish & draft cashflow. 2022-01-08 18:14:39 +02:00
elforjani13
90b4f86a0d fix(MoneyInForm): BIG-270 publish & draft cashflow. 2022-01-08 18:14:17 +02:00
Ahmed Bouhuolia
5766d25bd1 Merge pull request #18 from bigcapitalhq/BIG-271-hotjar-client-application-integration
`BIG-271` Hotjar client application integration.
2022-01-08 18:06:54 +02:00
elforjani13
6a5d96e869 BIG-271 Hotjar client application integration. 2022-01-08 17:59:30 +02:00
Ahmed Bouhuolia
11851d114d Merge pull request #16 from bigcapitalhq/develop
Release 1.5.5
2022-01-04 22:35:49 +02:00
a.bouhuolia
21779007be fix: application version. 2022-01-03 23:14:11 +02:00
a.bouhuolia
4fc1ecdc2d Merge branch 'main' of https://github.com/bigcapitalhq/client into main 2022-01-03 19:42:48 +02:00
a.bouhuolia
c9b5cecf7a Merge branch 'develop' into main 2022-01-03 19:42:23 +02:00
elforjani13
c31e9dcd29 fix: inventory adjustment & contacts drawer. 2022-01-03 14:35:50 +02:00
elforjani13
430ab95dc3 landed cost localiztion. 2022-01-03 13:38:22 +02:00
Ahmed Bouhuolia
8100a57195 Merge pull request #15 from bigcapitalhq/develop
Merge `develop` to `main`
2022-01-03 12:31:14 +02:00
61 changed files with 897 additions and 200 deletions

View File

@@ -2,6 +2,20 @@
All notable changes to Bigcapital server-side will be in this file. All notable changes to Bigcapital server-side will be in this file.
## [1.5.8] - 13-01-2022
### Added
- Add payment receive PDF print.
- Add credit note PDF print.
### Fixed
- fix: Payment receive initial loading state depends on request loading state instead fetching.
- fix: Balance sheet report alert positioning.
- fix: Separate customer and vendor inactivate and activate alerts.
- fix: Hide convert to invoice button if the invoice is already converted.
- fix: Customer and vendor balance summary percentage of column option.
- fix: Remove duplicated details in sales and purchases details drawers.
## [1.5.3] - 03-01-2020 ## [1.5.3] - 03-01-2020
### Fixed ### Fixed

View File

@@ -85,6 +85,9 @@ function getClientEnvironment(publicUrl) {
WDS_SOCKET_HOST: process.env.WDS_SOCKET_HOST, WDS_SOCKET_HOST: process.env.WDS_SOCKET_HOST,
WDS_SOCKET_PATH: process.env.WDS_SOCKET_PATH, WDS_SOCKET_PATH: process.env.WDS_SOCKET_PATH,
WDS_SOCKET_PORT: process.env.WDS_SOCKET_PORT, WDS_SOCKET_PORT: process.env.WDS_SOCKET_PORT,
// Application version.
VERSION: paths.appVersion
} }
); );
// Stringify all values so we can feed into webpack DefinePlugin // Stringify all values so we can feed into webpack DefinePlugin

View File

@@ -48,6 +48,8 @@ const resolveModule = (resolveFn, filePath) => {
return resolveFn(`${filePath}.js`); return resolveFn(`${filePath}.js`);
}; };
const appVersion = require(resolveApp('package.json')).version;
// config after eject: we're in ./config/ // config after eject: we're in ./config/
module.exports = { module.exports = {
dotenv: resolveApp('.env'), dotenv: resolveApp('.env'),
@@ -65,6 +67,7 @@ module.exports = {
proxySetup: resolveApp('src/setupProxy.js'), proxySetup: resolveApp('src/setupProxy.js'),
appNodeModules: resolveApp('node_modules'), appNodeModules: resolveApp('node_modules'),
publicUrlOrPath, publicUrlOrPath,
appVersion
}; };

View File

@@ -1,6 +1,6 @@
{ {
"name": "bigcapital-client", "name": "bigcapital-client",
"version": "1.5.3", "version": "1.5.8",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@babel/core": "7.8.4", "@babel/core": "7.8.4",

View File

@@ -2,7 +2,11 @@
<html dir="ltr" lang="en"> <html dir="ltr" lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicons/favicon-32.ico" sizes="32x32"> <link
rel="icon"
href="%PUBLIC_URL%/favicons/favicon-32.ico"
sizes="32x32"
/>
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" /> <meta name="theme-color" content="#000000" />
<meta <meta
@@ -15,6 +19,22 @@
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/ user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
--> -->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!-- Hotjar Tracking Code for https://app.bigcapital.ly/ -->
<script>
(function (h, o, t, j, a, r) {
h.hj =
h.hj ||
function () {
(h.hj.q = h.hj.q || []).push(arguments);
};
h._hjSettings = { hjid: 2774528, hjsv: 6 };
a = o.getElementsByTagName('head')[0];
r = o.createElement('script');
r.async = 1;
r.src = t + h._hjSettings.hjid + j + h._hjSettings.hjsv;
a.appendChild(r);
})(window, document, 'https://static.hotjar.com/c/hotjar-', '.js?sv=');
</script>
<!-- <!--
Notice the use of %PUBLIC_URL% in the tags above. Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build. It will be replaced with the URL of the `public` folder during the build.
@@ -41,7 +61,11 @@
To create a production bundle, use `npm run build` or `yarn build`. To create a production bundle, use `npm run build` or `yarn build`.
--> -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/flexboxgrid/6.3.1/flexboxgrid.min.css" type="text/css" > <link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/flexboxgrid/6.3.1/flexboxgrid.min.css"
type="text/css"
/>
<!-- <link href="https://cdn.syncfusion.com/ej2/material.css" rel="stylesheet"> --> <!-- <link href="https://cdn.syncfusion.com/ej2/material.css" rel="stylesheet"> -->
<!-- <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" /> --> <!-- <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" /> -->
</body> </body>

View File

@@ -21,5 +21,5 @@ export const CommercialDocEntriesTable = styled(DataTable)`
`; `;
export const CommercialDocFooter = styled.div` export const CommercialDocFooter = styled.div`
margin-top: 25px; margin-top: 28px;
`; `;

View File

@@ -32,6 +32,8 @@ import ReconcileVendorCreditDialog from '../containers/Dialogs/ReconcileVendorCr
import LockingTransactionsDialog from '../containers/Dialogs/LockingTransactionsDialog'; import LockingTransactionsDialog from '../containers/Dialogs/LockingTransactionsDialog';
import UnlockingTransactionsDialog from '../containers/Dialogs/UnlockingTransactionsDialog'; import UnlockingTransactionsDialog from '../containers/Dialogs/UnlockingTransactionsDialog';
import UnlockingPartialTransactionsDialog from '../containers/Dialogs/UnlockingPartialTransactionsDialog'; import UnlockingPartialTransactionsDialog from '../containers/Dialogs/UnlockingPartialTransactionsDialog';
import CreditNotePdfPreviewDialog from '../containers/Dialogs/CreditNotePdfPreviewDialog';
import PaymentReceivePdfPreviewDialog from '../containers/Dialogs/PaymentReceivePdfPreviewDialog';
/** /**
* Dialogs container. * Dialogs container.
@@ -74,6 +76,8 @@ export default function DialogsContainer() {
<UnlockingPartialTransactionsDialog <UnlockingPartialTransactionsDialog
dialogName={'unlocking-partial-transactions'} dialogName={'unlocking-partial-transactions'}
/> />
<CreditNotePdfPreviewDialog dialogName={'credit-note-pdf-preview'} />
<PaymentReceivePdfPreviewDialog dialogName={'payment-pdf-preview'} />
</div> </div>
); );
} }

View File

@@ -28,7 +28,7 @@ export default function Sidebar({ dashboardContentRef }) {
* @returns {React.JSX} * @returns {React.JSX}
*/ */
function SidebarFooterVersion() { function SidebarFooterVersion() {
const { REACT_APP_VERSION: VERSION } = process.env; const { VERSION } = process.env;
if (!VERSION) { if (!VERSION) {
return null; return null;

View File

@@ -57,9 +57,7 @@ function BillTransactionDeleteAlert({
loading={isLoading} loading={isLoading}
> >
<p> <p>
<T <T id={`landed_cost.once_your_delete_this_located_landed_cost`} />
id={`Once your delete this located landed cost, you won't be able to restore it later, Are your sure you want to delete this transaction?`}
/>
</p> </p>
</Alert> </Alert>
); );

View File

@@ -0,0 +1,67 @@
import React from 'react';
import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster } from 'components';
import { useActivateContact } from 'hooks/query';
import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect';
import withAlertActions from 'containers/Alert/withAlertActions';
import { compose } from 'utils';
/**
* Customer activate alert.
*/
function CustomerActivateAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { customerId, service },
// #withAlertActions
closeAlert,
}) {
const { mutateAsync: activateContact, isLoading } = useActivateContact();
// Handle activate constomer alert cancel.
const handleCancelActivateCustomer = () => {
closeAlert(name);
};
// Handle confirm customer activated.
const handleConfirmCustomerActivate = () => {
activateContact(customerId)
.then(() => {
AppToaster.show({
message: intl.get('customer.alert.activated_message'),
intent: Intent.SUCCESS,
});
})
.catch((error) => {})
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'activate'} />}
intent={Intent.WARNING}
isOpen={isOpen}
onCancel={handleCancelActivateCustomer}
loading={isLoading}
onConfirm={handleConfirmCustomerActivate}
>
<p>{intl.get('customer.alert.are_you_sure_want_to_activate_this_customer')}</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(CustomerActivateAlert);

View File

@@ -0,0 +1,69 @@
import React from 'react';
import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster } from 'components';
import { useInactivateContact } from 'hooks/query';
import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect';
import withAlertActions from 'containers/Alert/withAlertActions';
import { compose } from 'utils';
/**
* customer inactivate alert.
*/
function CustomerInactivateAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { customerId, service },
// #withAlertActions
closeAlert,
}) {
const { mutateAsync: inactivateContact, isLoading } = useInactivateContact();
// Handle cancel inactivate alert.
const handleCancelInactivateCustomer = () => {
closeAlert(name);
};
// Handle confirm contact Inactive.
const handleConfirmCustomerInactive = () => {
inactivateContact(customerId)
.then(() => {
AppToaster.show({
message: intl.get('the_contact_has_been_inactivated_successfully'),
intent: Intent.SUCCESS,
});
})
.catch((error) => {})
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'inactivate'} />}
intent={Intent.WARNING}
isOpen={isOpen}
onCancel={handleCancelInactivateCustomer}
onConfirm={handleConfirmCustomerInactive}
loading={isLoading}
>
<p>
{intl.get(
'customer.alert.are_you_sure_want_to_inactivate_this_customer',
)}
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(CustomerInactivateAlert);

View File

@@ -0,0 +1,69 @@
import React from 'react';
import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster } from 'components';
import { useActivateContact } from 'hooks/query';
import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect';
import withAlertActions from 'containers/Alert/withAlertActions';
import { compose } from 'utils';
/**
* Vendor activate alert.
*/
function VendorActivateAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { vendorId },
// #withAlertActions
closeAlert,
}) {
const { mutateAsync: activateContact, isLoading } = useActivateContact();
// Handle activate vendor alert cancel.
const handleCancelActivateVendor = () => {
closeAlert(name);
};
// Handle confirm vendor activated.
const handleConfirmVendorActivate = () => {
activateContact(vendorId)
.then(() => {
AppToaster.show({
message: intl.get('vendor.alert.activated_message'),
intent: Intent.SUCCESS,
});
})
.catch((error) => {})
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'activate'} />}
intent={Intent.WARNING}
isOpen={isOpen}
onCancel={handleCancelActivateVendor}
loading={isLoading}
onConfirm={handleConfirmVendorActivate}
>
<p>
{intl.get('vendor.alert.are_you_sure_want_to_activate_this_vendor')}
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(VendorActivateAlert);

View File

@@ -0,0 +1,68 @@
import React from 'react';
import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster } from 'components';
import { useInactivateContact } from 'hooks/query';
import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect';
import withAlertActions from 'containers/Alert/withAlertActions';
import { compose } from 'utils';
/**
* Vendor inactivate alert.
*/
function VendorInactivateAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { vendorId },
// #withAlertActions
closeAlert,
}) {
const { mutateAsync: inactivateContact, isLoading } = useInactivateContact();
// Handle cancel inactivate alert.
const handleCancelInactivateVendor = () => {
closeAlert(name);
};
// Handle confirm contact Inactive.
const handleConfirmVendorInactive = () => {
inactivateContact(vendorId)
.then(() => {
AppToaster.show({
message: intl.get('vendor.alert.inactivated_message'),
intent: Intent.SUCCESS,
});
})
.catch((error) => {})
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'inactivate'} />}
intent={Intent.WARNING}
isOpen={isOpen}
onCancel={handleCancelInactivateVendor}
onConfirm={handleConfirmVendorInactive}
loading={isLoading}
>
<p>
{intl.get('vendor.alert.are_you_sure_want_to_inactivate_this_vendor')}
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(VendorInactivateAlert);

View File

@@ -79,6 +79,10 @@ export const handleCashFlowTransactionType = (reference, openDrawer) => {
return openDrawer('refund-vendor-detail-drawer', { return openDrawer('refund-vendor-detail-drawer', {
refundTransactionId: reference.reference_id, refundTransactionId: reference.reference_id,
}); });
case 'InventoryAdjustment':
return openDrawer('inventory-adjustment-drawer', {
inventoryId: reference.reference_id,
});
default: default:
return openDrawer('cashflow-transaction-drawer', { return openDrawer('cashflow-transaction-drawer', {

View File

@@ -3,11 +3,11 @@ import React from 'react';
const CustomerDeleteAlert = React.lazy(() => const CustomerDeleteAlert = React.lazy(() =>
import('../Alerts/Customers/CustomerDeleteAlert'), import('../Alerts/Customers/CustomerDeleteAlert'),
); );
const ContactActivateAlert = React.lazy(() => const CustomerActivateAlert = React.lazy(() =>
import('../Alerts/Contacts/ContactActivateAlert'), import('../Alerts/Customers/CustomerActivateAlert'),
); );
const ContactInactivateAlert = React.lazy(() => const CustomerInactivateAlert = React.lazy(() =>
import('../Alerts/Contacts/ContactInactivateAlert'), import('../Alerts/Customers/CustomerInactivateAlert'),
); );
/** /**
@@ -15,6 +15,6 @@ const ContactInactivateAlert = React.lazy(() =>
*/ */
export default [ export default [
{ name: 'customer-delete', component: CustomerDeleteAlert }, { name: 'customer-delete', component: CustomerDeleteAlert },
{ name: 'contact-activate', component: ContactActivateAlert }, { name: 'customer-activate', component: CustomerActivateAlert },
{ name: 'contact-inactivate', component: ContactInactivateAlert }, { name: 'customer-inactivate', component: CustomerInactivateAlert },
]; ];

View File

@@ -89,15 +89,17 @@ function CustomersTable({
// Handle cancel/confirm inactive. // Handle cancel/confirm inactive.
const handleInactiveCustomer = ({ id, contact_service }) => { const handleInactiveCustomer = ({ id, contact_service }) => {
openAlert('contact-inactivate', { openAlert('customer-inactivate', {
contactId: id, customerId: id,
service: contact_service,
}); });
}; };
// Handle cancel/confirm activate. // Handle cancel/confirm activate.
const handleActivateCustomer = ({ id, contact_service }) => { const handleActivateCustomer = ({ id, contact_service }) => {
openAlert('contact-activate', { contactId: id, service: contact_service }); openAlert('customer-activate', {
customerId: id,
service: contact_service,
});
}; };
// Handle view detail contact. // Handle view detail contact.

View File

@@ -37,7 +37,7 @@ function AllocateLandedCostFloatingActions({
<DialogFooterActions alignment={'left'}> <DialogFooterActions alignment={'left'}>
{costTransactionEntry && ( {costTransactionEntry && (
<UnallocatedAmount> <UnallocatedAmount>
Unallocated cost Amount:{' '} <T id={'landed_cost.dialog.label_unallocated_cost_amount'}/>
<strong>{formattedUnallocatedCostAmount}</strong> <strong>{formattedUnallocatedCostAmount}</strong>
</UnallocatedAmount> </UnallocatedAmount>
)} )}

View File

@@ -42,7 +42,10 @@ function AllocateLandedCostForm({
.map((entry) => transformToForm(entry, defaultInitialValues.items[0])); .map((entry) => transformToForm(entry, defaultInitialValues.items[0]));
if (entries.length <= 0) { if (entries.length <= 0) {
AppToaster.show({ message: 'Something wrong!', intent: Intent.DANGER }); AppToaster.show({
message: intl.get('something_wrong'),
intent: Intent.DANGER,
});
return; return;
} }
const form = { const form = {
@@ -69,13 +72,14 @@ function AllocateLandedCostForm({
) )
) { ) {
AppToaster.show({ AppToaster.show({
message: message: intl.get(
'The total located cost is bigger than the transaction line.', 'landed_cost.error.the_total_located_cost_is_bigger_than_the_transaction_line',
),
intent: Intent.DANGER, intent: Intent.DANGER,
}); });
} else { } else {
AppToaster.show({ AppToaster.show({
message: 'Something went wrong!', message: intl.get('something_went_wrong'),
intent: Intent.DANGER, intent: Intent.DANGER,
}); });
} }

View File

@@ -0,0 +1,47 @@
import React from 'react';
import { AnchorButton } from '@blueprintjs/core';
import { DialogContent, PdfDocumentPreview, T } from 'components';
import { usePdfCreditNote } from 'hooks/query';
import withDialogActions from 'containers/Dialog/withDialogActions';
import { compose } from 'utils';
function CreditNotePdfPreviewDialogContent({
subscriptionForm: { creditNoteId },
}) {
const { isLoading, pdfUrl } = usePdfCreditNote(creditNoteId);
return (
<DialogContent>
<div class="dialog__header-actions">
<AnchorButton
href={pdfUrl}
target={'__blank'}
minimal={true}
outlined={true}
>
<T id={'pdf_preview.preview.button'} />
</AnchorButton>
<AnchorButton
href={pdfUrl}
download={'creditNote.pdf'}
minimal={true}
outlined={true}
>
<T id={'pdf_preview.download.button'} />
</AnchorButton>
</div>
<PdfDocumentPreview
height={760}
width={1000}
isLoading={isLoading}
url={pdfUrl}
/>
</DialogContent>
);
}
export default compose(withDialogActions)(CreditNotePdfPreviewDialogContent);

View File

@@ -0,0 +1,42 @@
import React from 'react';
import classNames from 'classnames';
import { T, Dialog, DialogSuspense } from 'components';
import withDialogRedux from 'components/DialogReduxConnect';
import { CLASSES } from 'common/classes';
import { compose } from 'utils';
const PdfPreviewDialogContent = React.lazy(() =>
import('./CreditNotePdfPreviewDialogContent'),
);
/**
* Credit note PDF previwe dialog.
*/
function CreditNotePdfPreviewDialog({
dialogName,
payload = { creditNoteId: null },
isOpen,
}) {
return (
<Dialog
name={dialogName}
title={<T id={'credit_note_preview.dialog.title'} />}
className={classNames(CLASSES.DIALOG_PDF_PREVIEW)}
autoFocus={true}
canEscapeKeyClose={true}
isOpen={isOpen}
style={{ width: '1000px' }}
>
<DialogSuspense>
<PdfPreviewDialogContent
dialogName={dialogName}
subscriptionForm={payload}
/>
</DialogSuspense>
</Dialog>
);
}
export default compose(withDialogRedux())(CreditNotePdfPreviewDialog);

View File

@@ -29,7 +29,7 @@ const defaultInitialValues = {
cashflow_account_id: '', cashflow_account_id: '',
credit_account_id: '', credit_account_id: '',
description: '', description: '',
published: '', publish: '',
}; };
function MoneyInForm({ function MoneyInForm({
@@ -73,7 +73,7 @@ function MoneyInForm({
const handleFormSubmit = (values, { setSubmitting, setErrors }) => { const handleFormSubmit = (values, { setSubmitting, setErrors }) => {
const form = { const form = {
...omit(values, ['currency_code']), ...omit(values, ['currency_code']),
published: true, publish: true,
}; };
setSubmitting(true); setSubmitting(true);
createCashflowTransactionMutate(form) createCashflowTransactionMutate(form)

View File

@@ -14,7 +14,7 @@ const Schema = Yup.object().shape({
.min(3) .min(3)
.max(DATATYPES_LENGTH.TEXT) .max(DATATYPES_LENGTH.TEXT)
.label(intl.get('description')), .label(intl.get('description')),
published: Yup.boolean(), publish: Yup.boolean(),
}); });
export const CreateMoneyInFormSchema = Schema; export const CreateMoneyInFormSchema = Schema;

View File

@@ -29,7 +29,7 @@ const defaultInitialValues = {
cashflow_account_id: '', cashflow_account_id: '',
credit_account_id: '', credit_account_id: '',
description: '', description: '',
published: '', publish: '',
}; };
function MoneyOutForm({ function MoneyOutForm({
@@ -73,7 +73,7 @@ function MoneyOutForm({
const handleFormSubmit = (values, { setSubmitting, setErrors }) => { const handleFormSubmit = (values, { setSubmitting, setErrors }) => {
const form = { const form = {
...omit(values, ['currency_code']), ...omit(values, ['currency_code']),
published: true, publish: true,
}; };
setSubmitting(true); setSubmitting(true);
createCashflowTransactionMutate(form) createCashflowTransactionMutate(form)

View File

@@ -14,7 +14,7 @@ const Schema = Yup.object().shape({
.min(3) .min(3)
.max(DATATYPES_LENGTH.TEXT) .max(DATATYPES_LENGTH.TEXT)
.label(intl.get('description')), .label(intl.get('description')),
published: Yup.boolean(), publish: Yup.boolean(),
}); });
export const CreateMoneyOutSchema = Schema; export const CreateMoneyOutSchema = Schema;

View File

@@ -0,0 +1,49 @@
import React from 'react';
import { AnchorButton } from '@blueprintjs/core';
import { DialogContent, PdfDocumentPreview, T } from 'components';
import { usePdfPaymentReceive } from 'hooks/query';
import withDialogActions from 'containers/Dialog/withDialogActions';
import { compose } from 'utils';
function PaymentReceivePdfPreviewDialogContent({
subscriptionForm: { paymentReceiveId },
}) {
const { isLoading, pdfUrl } = usePdfPaymentReceive(paymentReceiveId);
return (
<DialogContent>
<div class="dialog__header-actions">
<AnchorButton
href={pdfUrl}
target={'__blank'}
minimal={true}
outlined={true}
>
<T id={'pdf_preview.preview.button'} />
</AnchorButton>
<AnchorButton
href={pdfUrl}
download={'payment.pdf'}
minimal={true}
outlined={true}
>
<T id={'pdf_preview.download.button'} />
</AnchorButton>
</div>
<PdfDocumentPreview
height={760}
width={1000}
isLoading={isLoading}
url={pdfUrl}
/>
</DialogContent>
);
}
export default compose(withDialogActions)(
PaymentReceivePdfPreviewDialogContent,
);

View File

@@ -0,0 +1,44 @@
import React from 'react';
import classNames from 'classnames';
import { T, Dialog, DialogSuspense } from 'components';
import withDialogRedux from 'components/DialogReduxConnect';
import { CLASSES } from 'common/classes';
import { compose } from 'utils';
// Lazy loading the content.
const PdfPreviewDialogContent = React.lazy(() =>
import('./PaymentReceivePdfPreviewContent'),
);
/**
* Payment receive PDF preview dialog.
*/
function PaymentReceivePdfPreviewDialog({
dialogName,
payload = { paymentReceiveId: null },
isOpen,
}) {
return (
<Dialog
name={dialogName}
title={<T id={'payment_receive_preview.dialog.title'} />}
className={classNames(CLASSES.DIALOG_PDF_PREVIEW)}
autoFocus={true}
canEscapeKeyClose={true}
isOpen={isOpen}
style={{ width: '1000px' }}
>
<DialogSuspense>
<PdfPreviewDialogContent
dialogName={dialogName}
subscriptionForm={payload}
/>
</DialogSuspense>
</Dialog>
);
}
export default compose(withDialogRedux())(PaymentReceivePdfPreviewDialog);

View File

@@ -65,6 +65,11 @@ function CreditNoteDetailActionsBar({
openDialog('reconcile-credit-note', { creditNoteId }); openDialog('reconcile-credit-note', { creditNoteId });
}; };
// Handle print credit note.
const handlePrintCreditNote = () => {
openDialog('credit-note-pdf-preview', { creditNoteId });
};
return ( return (
<DrawerActionsBar> <DrawerActionsBar>
<NavbarGroup> <NavbarGroup>
@@ -88,6 +93,14 @@ function CreditNoteDetailActionsBar({
<NavbarDivider /> <NavbarDivider />
</If> </If>
</Can> </Can>
<Can I={CreditNoteAction.View} a={AbilitySubject.CreditNote}>
<Button
className={Classes.MINIMAL}
icon={<Icon icon="print-16" />}
text={<T id={'print'} />}
onClick={handlePrintCreditNote}
/>
</Can>
<Can I={CreditNoteAction.Delete} a={AbilitySubject.CreditNote}> <Can I={CreditNoteAction.Delete} a={AbilitySubject.CreditNote}>
<Button <Button
className={Classes.MINIMAL} className={Classes.MINIMAL}

View File

@@ -15,9 +15,14 @@ import { useCreditNoteDetailDrawerContext } from './CreditNoteDetailDrawerProvid
*/ */
export default function CreditNoteDetailFooter() { export default function CreditNoteDetailFooter() {
const { creditNote } = useCreditNoteDetailDrawerContext(); const { creditNote } = useCreditNoteDetailDrawerContext();
return ( return (
<CommercialDocFooter> <CommercialDocFooter>
<DetailsMenu direction={'horizantal'} minLabelSize={'180px'}> <DetailsMenu direction={'horizantal'} minLabelSize={'180px'}>
<If condition={creditNote.terms_conditions}>
<DetailItem label={<T id={'note'} />} children={creditNote.note} />
</If>
<If condition={creditNote.terms_conditions}> <If condition={creditNote.terms_conditions}>
<DetailItem label={<T id={'terms_conditions'} />}> <DetailItem label={<T id={'terms_conditions'} />}>
{creditNote.terms_conditions} {creditNote.terms_conditions}

View File

@@ -42,6 +42,12 @@ export default function CreditNoteDetailHeader() {
<Row> <Row>
<Col xs={6}> <Col xs={6}>
<DetailsMenu direction={'horizantal'} minLabelSize={'180px'}> <DetailsMenu direction={'horizantal'} minLabelSize={'180px'}>
<DetailItem
label={intl.get('credit_note.drawer.label_credit_note_date')}
>
<FormatDate value={creditNote.formatted_credit_note_date} />
</DetailItem>
<DetailItem <DetailItem
label={intl.get('credit_note.drawer.label_credit_note_no')} label={intl.get('credit_note.drawer.label_credit_note_no')}
> >
@@ -53,12 +59,6 @@ export default function CreditNoteDetailHeader() {
{creditNote.customer?.display_name} {creditNote.customer?.display_name}
</CustomerDrawerLink> </CustomerDrawerLink>
</DetailItem> </DetailItem>
<DetailItem
label={intl.get('credit_note.drawer.label_credit_note_date')}
>
<FormatDate value={creditNote.formatted_credit_note_date} />
</DetailItem>
</DetailsMenu> </DetailsMenu>
</Col> </Col>
@@ -77,11 +77,6 @@ export default function CreditNoteDetailHeader() {
label={intl.get('reference')} label={intl.get('reference')}
children={defaultTo(creditNote.reference_no, '-')} children={defaultTo(creditNote.reference_no, '-')}
/> />
<DetailItem
label={intl.get('note')}
children={defaultTo(creditNote.note, '-')}
/>
<DetailItem <DetailItem
label={<T id={'credit_note.drawer.label_created_at'} />} label={<T id={'credit_note.drawer.label_created_at'} />}
children={<FormatDate value={creditNote.created_at} />} children={<FormatDate value={creditNote.created_at} />}

View File

@@ -12,7 +12,6 @@ import {
DetailItem, DetailItem,
Row, Row,
Col, Col,
ButtonLink,
CustomerDrawerLink, CustomerDrawerLink,
} from 'components'; } from 'components';
import { useEstimateDetailDrawerContext } from './EstimateDetailDrawerProvider'; import { useEstimateDetailDrawerContext } from './EstimateDetailDrawerProvider';

View File

@@ -1,42 +1,29 @@
import React from 'react'; import React from 'react';
import styled from 'styled-components';
import { import {
T, T,
TotalLines, CommercialDocFooter,
TotalLine, DetailsMenu,
TotalLineBorderStyle, If,
TotalLineTextStyle, DetailItem,
} from 'components'; } from 'components';
import { usePaymentMadeDetailContext } from './PaymentMadeDetailProvider'; import { usePaymentMadeDetailContext } from './PaymentMadeDetailProvider';
/** /**
* Payment made - Details panel - Footer. * Payment made - Details panel - Footer.
*/ */
export default function PaymentMadeDetailFooter() { export function PaymentMadeDetailFooter() {
const { paymentMade } = usePaymentMadeDetailContext(); const { paymentMade } = usePaymentMadeDetailContext();
return ( return (
<PaymentMadeFooterRoot> <CommercialDocFooter>
<PaymentMadeTotalLines labelColWidth={'180px'} amountColWidth={'180px'}> <DetailsMenu direction={'horizantal'} minLabelSize={'180px'}>
<TotalLine <If condition={paymentMade.statement}>
title={<T id={'payment_made.details.subtotal'} />} <DetailItem label={<T id={'payment_made.details.statement'} />}>
value={paymentMade.amount} {paymentMade.statement}
borderStyle={TotalLineBorderStyle.SingleDark} </DetailItem>
/> </If>
<TotalLine </DetailsMenu>
title={<T id={'payment_made.details.total'} />} </CommercialDocFooter>
value={paymentMade.formatted_amount}
borderStyle={TotalLineBorderStyle.DoubleDark}
textStyle={TotalLineTextStyle.Bold}
/>
</PaymentMadeTotalLines>
</PaymentMadeFooterRoot>
); );
} }
export const PaymentMadeFooterRoot = styled.div``;
export const PaymentMadeTotalLines = styled(TotalLines)`
margin-left: auto;
`;

View File

@@ -34,6 +34,10 @@ export default function PaymentMadeDetailHeader() {
<Row> <Row>
<Col xs={6}> <Col xs={6}>
<DetailsMenu direction={'horizantal'} minLabelSize={'180px'}> <DetailsMenu direction={'horizantal'} minLabelSize={'180px'}>
<DetailItem
label={intl.get('payment_date')}
children={<FormatDate value={paymentMade.payment_date} />}
/>
<DetailItem <DetailItem
label={intl.get('payment_made.details.payment_number')} label={intl.get('payment_made.details.payment_number')}
children={defaultTo(paymentMade.payment_number, '-')} children={defaultTo(paymentMade.payment_number, '-')}
@@ -47,11 +51,6 @@ export default function PaymentMadeDetailHeader() {
label={intl.get('payment_account')} label={intl.get('payment_account')}
children={paymentMade.payment_account?.name} children={paymentMade.payment_account?.name}
/> />
<DetailItem
label={intl.get('payment_date')}
children={<FormatDate value={paymentMade.payment_date} />}
/>
</DetailsMenu> </DetailsMenu>
</Col> </Col>
<Col xs={6}> <Col xs={6}>
@@ -61,8 +60,8 @@ export default function PaymentMadeDetailHeader() {
minLabelSize={'180px'} minLabelSize={'180px'}
> >
<DetailItem <DetailItem
label={intl.get('description')} label={intl.get('reference')}
children={defaultTo(paymentMade.statement, '-')} children={defaultTo(paymentMade.reference, '-')}
/> />
<DetailItem <DetailItem
label={intl.get('created_at')} label={intl.get('created_at')}

View File

@@ -20,8 +20,7 @@ function PaymentMadeDetailProvider({ paymentMadeId, ...props }) {
enabled: !!paymentMadeId, enabled: !!paymentMadeId,
}, },
); );
// Provider state.
//provider.
const provider = { const provider = {
paymentMadeId, paymentMadeId,
paymentMade, paymentMade,

View File

@@ -4,7 +4,8 @@ import { CommercialDocBox } from 'components';
import PaymentMadeDetailHeader from './PaymentMadeDetailHeader'; import PaymentMadeDetailHeader from './PaymentMadeDetailHeader';
import PaymentMadeDetailTable from './PaymentMadeDetailTable'; import PaymentMadeDetailTable from './PaymentMadeDetailTable';
import PaymentMadeDetailFooter from './PaymentMadeDetailFooter'; import PaymentMadeDetailTableFooter from './PaymentMadeDetailTableFooter';
import { PaymentMadeDetailFooter } from './PaymentMadeDetailFooter';
/** /**
* Payment made detail tab. * Payment made detail tab.
@@ -15,6 +16,7 @@ export default function PaymentMadeDetailTab() {
<CommercialDocBox> <CommercialDocBox>
<PaymentMadeDetailHeader /> <PaymentMadeDetailHeader />
<PaymentMadeDetailTable /> <PaymentMadeDetailTable />
<PaymentMadeDetailTableFooter />
<PaymentMadeDetailFooter /> <PaymentMadeDetailFooter />
</CommercialDocBox> </CommercialDocBox>
); );

View File

@@ -0,0 +1,42 @@
import React from 'react';
import styled from 'styled-components';
import {
T,
TotalLines,
TotalLine,
TotalLineBorderStyle,
TotalLineTextStyle,
} from 'components';
import { usePaymentMadeDetailContext } from './PaymentMadeDetailProvider';
/**
* Payment made - Details panel - Footer.
*/
export default function PaymentMadeDetailTableFooter() {
const { paymentMade } = usePaymentMadeDetailContext();
return (
<PaymentMadeFooterRoot>
<PaymentMadeTotalLines labelColWidth={'180px'} amountColWidth={'180px'}>
<TotalLine
title={<T id={'payment_made.details.subtotal'} />}
value={paymentMade.amount}
borderStyle={TotalLineBorderStyle.SingleDark}
/>
<TotalLine
title={<T id={'payment_made.details.total'} />}
value={paymentMade.formatted_amount}
borderStyle={TotalLineBorderStyle.DoubleDark}
textStyle={TotalLineTextStyle.Bold}
/>
</PaymentMadeTotalLines>
</PaymentMadeFooterRoot>
);
}
export const PaymentMadeFooterRoot = styled.div``;
export const PaymentMadeTotalLines = styled(TotalLines)`
margin-left: auto;
`;

View File

@@ -62,6 +62,11 @@ function PaymentReceiveActionsBar({
openDialog('notify-payment-via-sms', { paymentReceiveId }); openDialog('notify-payment-via-sms', { paymentReceiveId });
}; };
// Handle print payment receive.
const handlePrintPaymentReceive = () => {
openDialog('payment-pdf-preview', { paymentReceiveId });
};
return ( return (
<DrawerActionsBar> <DrawerActionsBar>
<NavbarGroup> <NavbarGroup>
@@ -74,6 +79,14 @@ function PaymentReceiveActionsBar({
/> />
<NavbarDivider /> <NavbarDivider />
</Can> </Can>
<Can I={PaymentReceiveAction.View} a={AbilitySubject.PaymentReceive}>
<Button
className={Classes.MINIMAL}
icon={<Icon icon="print-16" />}
text={<T id={'print'} />}
onClick={handlePrintPaymentReceive}
/>
</Can>
<Can I={PaymentReceiveAction.Delete} a={AbilitySubject.PaymentReceive}> <Can I={PaymentReceiveAction.Delete} a={AbilitySubject.PaymentReceive}>
<Button <Button
className={Classes.MINIMAL} className={Classes.MINIMAL}

View File

@@ -10,7 +10,6 @@ import {
DetailItem, DetailItem,
CommercialDocHeader, CommercialDocHeader,
CommercialDocTopHeader, CommercialDocTopHeader,
ButtonLink,
CustomerDrawerLink, CustomerDrawerLink,
} from 'components'; } from 'components';
import { usePaymentReceiveDetailContext } from './PaymentReceiveDetailProvider'; import { usePaymentReceiveDetailContext } from './PaymentReceiveDetailProvider';
@@ -34,6 +33,10 @@ export default function PaymentReceiveDetailHeader() {
<Row> <Row>
<Col xs={6}> <Col xs={6}>
<DetailsMenu direction={'horizantal'} minLabelSize={'180px'}> <DetailsMenu direction={'horizantal'} minLabelSize={'180px'}>
<DetailItem
label={intl.get('payment_date')}
children={<FormatDate value={paymentReceive.payment_date} />}
/>
<DetailItem <DetailItem
label={intl.get('payment_receive.details.payment_number')} label={intl.get('payment_receive.details.payment_number')}
children={defaultTo(paymentReceive.payment_receive_no, '-')} children={defaultTo(paymentReceive.payment_receive_no, '-')}
@@ -48,10 +51,6 @@ export default function PaymentReceiveDetailHeader() {
label={intl.get('deposit_account')} label={intl.get('deposit_account')}
children={paymentReceive.deposit_account?.name} children={paymentReceive.deposit_account?.name}
/> />
<DetailItem
label={intl.get('payment_date')}
children={<FormatDate value={paymentReceive.payment_date} />}
/>
</DetailsMenu> </DetailsMenu>
</Col> </Col>
@@ -62,8 +61,8 @@ export default function PaymentReceiveDetailHeader() {
minLabelSize={'180px'} minLabelSize={'180px'}
> >
<DetailItem <DetailItem
label={intl.get('description')} label={intl.get('reference')}
children={defaultTo(paymentReceive.statement, '')} children={defaultTo(paymentReceive.reference_no, '-')}
/> />
<DetailItem <DetailItem
label={intl.get('created_at')} label={intl.get('created_at')}

View File

@@ -0,0 +1,23 @@
import React from 'react';
import {
CommercialDocFooter,
T,
If,
DetailsMenu,
DetailItem,
} from '../../../components';
import { useVendorCreditDetailDrawerContext } from './VendorCreditDetailDrawerProvider';
export function VendorCreditDetailFooter() {
const { vendorCredit } = useVendorCreditDetailDrawerContext();
return (
<CommercialDocFooter>
<DetailsMenu direction={'horizantal'} minLabelSize={'150px'}>
<If condition={vendorCredit.note}>
<DetailItem label={<T id={'note'} />} children={vendorCredit.note} />
</If>
</DetailsMenu>
</CommercialDocFooter>
);
}

View File

@@ -38,6 +38,11 @@ export default function VendorCreditDetailHeader() {
<Row> <Row>
<Col xs={6}> <Col xs={6}>
<DetailsMenu direction={'horizantal'} minLabelSize={'180px'}> <DetailsMenu direction={'horizantal'} minLabelSize={'180px'}>
<DetailItem
label={intl.get('vendor_credit.drawer.label_vendor_credit_date')}
>
<FormatDate value={vendorCredit.formatted_vendor_credit_date} />
</DetailItem>
<DetailItem <DetailItem
label={intl.get('vendor_credit.drawer.label_vendor_credit_no')} label={intl.get('vendor_credit.drawer.label_vendor_credit_no')}
> >
@@ -49,12 +54,6 @@ export default function VendorCreditDetailHeader() {
{vendorCredit.vendor?.display_name} {vendorCredit.vendor?.display_name}
</VendorDrawerLink> </VendorDrawerLink>
</DetailItem> </DetailItem>
<DetailItem
label={intl.get('vendor_credit.drawer.label_vendor_credit_date')}
>
<FormatDate value={vendorCredit.formatted_vendor_credit_date} />
</DetailItem>
</DetailsMenu> </DetailsMenu>
</Col> </Col>
<Col xs={6}> <Col xs={6}>
@@ -72,10 +71,6 @@ export default function VendorCreditDetailHeader() {
label={intl.get('reference')} label={intl.get('reference')}
children={defaultTo(vendorCredit.reference_no, '-')} children={defaultTo(vendorCredit.reference_no, '-')}
/> />
<DetailItem
label={intl.get('note')}
children={defaultTo(vendorCredit.note, '-')}
/>
<DetailItem <DetailItem
label={<T id={'vendor_credit.drawer.label_created_at'} />} label={<T id={'vendor_credit.drawer.label_created_at'} />}
children={<FormatDate value={vendorCredit.created_at} />} children={<FormatDate value={vendorCredit.created_at} />}

View File

@@ -5,6 +5,7 @@ import { CommercialDocBox } from 'components';
import VendorCreditDetailHeader from './VendorCreditDetailHeader'; import VendorCreditDetailHeader from './VendorCreditDetailHeader';
import VendorCreditDetailTable from './VendorCreditDetailTable'; import VendorCreditDetailTable from './VendorCreditDetailTable';
import VendorCreditDetailDrawerFooter from './VendorCreditDetailDrawerFooter'; import VendorCreditDetailDrawerFooter from './VendorCreditDetailDrawerFooter';
import { VendorCreditDetailFooter } from './VendorCreditDetailFooter';
/** /**
* Vendor credit details panel. * Vendor credit details panel.
@@ -16,6 +17,7 @@ export default function VendorCreditDetailPanel() {
<VendorCreditDetailHeader /> <VendorCreditDetailHeader />
<VendorCreditDetailTable /> <VendorCreditDetailTable />
<VendorCreditDetailDrawerFooter /> <VendorCreditDetailDrawerFooter />
<VendorCreditDetailFooter />
</CommercialDocBox> </CommercialDocBox>
); );
} }

View File

@@ -67,6 +67,7 @@ function BalanceSheet({
onNumberFormatSubmit={handleNumberFormatSubmit} onNumberFormatSubmit={handleNumberFormatSubmit}
/> />
<BalanceSheetLoadingBar /> <BalanceSheetLoadingBar />
<BalanceSheetAlerts />
<DashboardPageContent> <DashboardPageContent>
<FinancialStatement> <FinancialStatement>
@@ -80,7 +81,6 @@ function BalanceSheet({
</FinancialStatement> </FinancialStatement>
</DashboardPageContent> </DashboardPageContent>
<BalanceSheetAlerts />
</BalanceSheetProvider> </BalanceSheetProvider>
); );
} }

View File

@@ -70,6 +70,7 @@ function CashFlowStatement({
/> />
<CashFlowStatementLoadingBar /> <CashFlowStatementLoadingBar />
<CashFlowStatementAlerts /> <CashFlowStatementAlerts />
<DashboardPageContent> <DashboardPageContent>
<FinancialStatement> <FinancialStatement>
<CashFlowStatementHeader <CashFlowStatementHeader

View File

@@ -52,7 +52,7 @@ export default function CustomersBalanceSummaryGeneralPanelContent() {
<Row> <Row>
<Col xs={5}> <Col xs={5}>
<FastField name={'percentage'} type={'checkbox'}> <FastField name={'percentage_column'} type={'checkbox'}>
{({ field }) => ( {({ field }) => (
<FormGroup labelInfo={<FieldHint />}> <FormGroup labelInfo={<FieldHint />}>
<Checkbox <Checkbox

View File

@@ -1,6 +1,5 @@
import React, { useMemo, useCallback } from 'react'; import React from 'react';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import classNames from 'classnames';
import FinancialSheet from 'components/FinancialSheet'; import FinancialSheet from 'components/FinancialSheet';
import DataTable from 'components/DataTable'; import DataTable from 'components/DataTable';
@@ -15,11 +14,9 @@ export default function CustomersBalanceSummaryTable({
// #ownProps // #ownProps
companyName, companyName,
}) { }) {
const { const {
isCustomersBalanceLoading, isCustomersBalanceLoading,
CustomerBalanceSummary: { tableRows }, CustomerBalanceSummary: { table },
} = useCustomersBalanceSummaryContext(); } = useCustomersBalanceSummaryContext();
const columns = useCustomersSummaryColumns(); const columns = useCustomersSummaryColumns();
@@ -39,7 +36,7 @@ export default function CustomersBalanceSummaryTable({
<DataTable <DataTable
className="bigcapital-datatable--financial-report" className="bigcapital-datatable--financial-report"
columns={columns} columns={columns}
data={tableRows} data={table.data}
rowClassNames={rowClassNames} rowClassNames={rowClassNames}
noInitialFetch={true} noInitialFetch={true}
/> />

View File

@@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import * as R from 'ramda';
import { If } from 'components'; import { If } from 'components';
import FinancialLoadingBar from '../FinancialLoadingBar'; import FinancialLoadingBar from '../FinancialLoadingBar';
@@ -9,29 +10,53 @@ import { useCustomersBalanceSummaryContext } from './CustomersBalanceSummaryProv
* Retrieve customers balance summary columns. * Retrieve customers balance summary columns.
*/ */
export const useCustomersSummaryColumns = () => { export const useCustomersSummaryColumns = () => {
return React.useMemo( const {
() => [ CustomerBalanceSummary: { table },
{ } = useCustomersBalanceSummaryContext();
Header: intl.get('customer_name'),
accessor: 'cells[0].value', return React.useMemo(() => {
className: 'customer_name', return dynamicColumns(table.columns || []);
width: 240, }, [table.columns]);
}, };
{
Header: intl.get('total'), /**
accessor: 'cells[1].value', * Account name column accessor.
className: 'total', */
width: 140, const accountNameColumnAccessor = () => ({
}, Header: intl.get('customer_name'),
{ accessor: 'cells[0].value',
Header: intl.get('percentage_of_column'), className: 'customer_name',
accessor: 'cells[2].value', width: 240,
className: 'total', });
width: 140,
}, /**
], * Total column accessor.
[], */
); const totalColumnAccessor = () => ({
Header: intl.get('total'),
accessor: 'cells[1].value',
className: 'total',
width: 140,
});
/**
* Percentage column accessor.
*/
const percentageColumnAccessor = () => ({
Header: intl.get('percentage_of_column'),
accessor: 'cells[2].value',
className: 'total',
width: 140,
});
const dynamicColumns = (columns) => {
return R.map(
R.compose(
R.when(R.pathEq(['key'], 'name'), accountNameColumnAccessor),
R.when(R.pathEq(['key'], 'total'), totalColumnAccessor),
R.when(R.pathEq(['key'], 'percentage_of_column'), percentageColumnAccessor),
),
)(columns);
}; };
/** /**

View File

@@ -58,14 +58,14 @@ export default function VendorsBalanceSummaryHeaderGeneralContent() {
<Row> <Row>
<Col xs={5}> <Col xs={5}>
<FastField name={'percentage'} type={'checkbox'}> <FastField name={'percentage_column'} type={'checkbox'}>
{({ field }) => ( {({ field }) => (
<FormGroup labelInfo={<FieldHint />}> <FormGroup labelInfo={<FieldHint />}>
<Checkbox <Checkbox
inline={true} inline={true}
small={true} small={true}
label={<T id={'percentage_of_column'} />} label={<T id={'percentage_of_column'} />}
name={'percentage'} name={'percentage_column'}
{...field} {...field}
/> />
</FormGroup> </FormGroup>

View File

@@ -14,10 +14,8 @@ export default function VendorsBalanceSummaryTable({
//#ownProps //#ownProps
organizationName, organizationName,
}) { }) {
const { const {
VendorBalanceSummary, VendorBalanceSummary: { table },
isVendorsBalanceLoading, isVendorsBalanceLoading,
} = useVendorsBalanceSummaryContext(); } = useVendorsBalanceSummaryContext();
@@ -39,7 +37,7 @@ export default function VendorsBalanceSummaryTable({
<DataTable <DataTable
className={'bigcapital-datatable--financial-report'} className={'bigcapital-datatable--financial-report'}
columns={columns} columns={columns}
data={VendorBalanceSummary?.tableRows} data={table?.data}
rowClassNames={rowClassNames} rowClassNames={rowClassNames}
noInitialFetch={true} noInitialFetch={true}
/> />

View File

@@ -1,8 +1,8 @@
import React, { useMemo } from 'react'; import React from 'react';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import * as R from 'ramda';
import { If } from 'components'; import { If } from 'components';
import { getColumnWidth } from 'utils';
import FinancialLoadingBar from '../FinancialLoadingBar'; import FinancialLoadingBar from '../FinancialLoadingBar';
import { useVendorsBalanceSummaryContext } from './VendorsBalanceSummaryProvider'; import { useVendorsBalanceSummaryContext } from './VendorsBalanceSummaryProvider';
@@ -10,28 +10,65 @@ import { useVendorsBalanceSummaryContext } from './VendorsBalanceSummaryProvider
* Retrieve vendors balance summary columns. * Retrieve vendors balance summary columns.
*/ */
export const useVendorsBalanceColumns = () => { export const useVendorsBalanceColumns = () => {
return useMemo(() => [ const {
{ VendorBalanceSummary: { table },
Header: intl.get('vendor_name'), } = useVendorsBalanceSummaryContext();
accessor: 'cells[0].value',
className: 'customer_name', return React.useMemo(() => {
width: 240, return dynamicColumns(table.columns || []);
sticky: 'left', }, [table.columns]);
textOverview: true, };
},
{ /**
Header: intl.get('total'), * Vendor name accessor.
accessor: 'cells[1].value', */
className: 'total', const vendorColumnAccessor = () => ({
width: 140, Header: intl.get('vendor_name'),
}, accessor: 'cells[0].value',
{ className: 'vendor_name',
Header: intl.get('percentage_of_column'), width: 240,
accessor: 'cells[2].value', align: 'left',
// className: 'total', textOverview: true,
width: 140, });
},
]); /**
* Percentage column accessor.
*/
const percentageColumnAccessor = () => ({
Header: intl.get('percentage_of_column'),
accessor: 'cells[2].value',
className: 'total',
width: 140,
align: 'right',
textOverview: true,
});
/**
* Total column accessor.
*/
const totalColumnAccessor = () => ({
Header: intl.get('total'),
accessor: 'cells[1].value',
className: 'total',
width: 140,
align: 'right',
textOverview: true,
});
/**
* Composes the response columns to table component columns.
*/
const dynamicColumns = (columns) => {
return R.map(
R.compose(
R.when(R.pathEq(['key'], 'name'), vendorColumnAccessor),
R.when(R.pathEq(['key'], 'total'), totalColumnAccessor),
R.when(
R.pathEq(['key'], 'percentage_of_column'),
percentageColumnAccessor,
),
),
)(columns);
}; };
/** /**

View File

@@ -3,7 +3,6 @@ import { isEmpty } from 'lodash';
import { import {
getFieldsFromResourceMeta, getFieldsFromResourceMeta,
transformTableQueryToParams, transformTableQueryToParams,
isTableEmptyStatus,
} from 'utils'; } from 'utils';
import { transformItemsTableState } from './utils'; import { transformItemsTableState } from './utils';

View File

@@ -83,11 +83,13 @@ export function ActionsMenu({
text={intl.get('edit_estimate')} text={intl.get('edit_estimate')}
onClick={safeCallback(onEdit, original)} onClick={safeCallback(onEdit, original)}
/> />
<MenuItem <If condition={!original.is_converted_to_invoice}>
icon={<Icon icon="convert_to" />} <MenuItem
text={intl.get('convert_to_invoice')} icon={<Icon icon="convert_to" />}
onClick={safeCallback(onConvert, original)} text={intl.get('convert_to_invoice')}
/> onClick={safeCallback(onConvert, original)}
/>
</If>
<If condition={!original.is_delivered}> <If condition={!original.is_delivered}>
<MenuItem <MenuItem

View File

@@ -11,12 +11,11 @@ const InvoicesDrawerContent = lazy(() => import('./InvoiceDrawerContent'));
*/ */
function InvoiceDrawer({ function InvoiceDrawer({
name, name,
//#withDrawer //#withDrawer
isOpen, isOpen,
payload: { invoiceId }, payload: { invoiceId },
}) { }) {
return ( return (
<Drawer isOpen={isOpen} name={name}> <Drawer isOpen={isOpen} name={name}>
<DrawerSuspense> <DrawerSuspense>

View File

@@ -16,7 +16,7 @@ const PaymentReceivesListContext = createContext();
*/ */
function PaymentReceivesListProvider({ query, tableStateChanged, ...props }) { function PaymentReceivesListProvider({ query, tableStateChanged, ...props }) {
// Fetch payment receives resource views and fields. // Fetch payment receives resource views and fields.
const { data: paymentReceivesViews, isFetching: isViewsLoading } = const { data: paymentReceivesViews, isLoading: isViewsLoading } =
useResourceViews('payment_receives'); useResourceViews('payment_receives');
// Fetch the payment receives resource fields. // Fetch the payment receives resource fields.

View File

@@ -2,7 +2,7 @@ import React from 'react';
import 'style/pages/PaymentReceive/List.scss'; import 'style/pages/PaymentReceive/List.scss';
import { DashboardContentTable, DashboardPageContent } from 'components'; import { DashboardPageContent } from 'components';
import PaymentReceiveActionsBar from './PaymentReceiveActionsBar'; import PaymentReceiveActionsBar from './PaymentReceiveActionsBar';
import { PaymentReceivesListProvider } from './PaymentReceiptsListProvider'; import { PaymentReceivesListProvider } from './PaymentReceiptsListProvider';
import PaymentReceiveViewTabs from './PaymentReceiveViewTabs'; import PaymentReceiveViewTabs from './PaymentReceiveViewTabs';

View File

@@ -3,15 +3,15 @@ import React from 'react';
const VendorDeleteAlert = React.lazy(() => const VendorDeleteAlert = React.lazy(() =>
import('../Alerts/Vendors/VendorDeleteAlert'), import('../Alerts/Vendors/VendorDeleteAlert'),
); );
const ContactActivateAlert = React.lazy(() => const VendorActivateAlert = React.lazy(() =>
import('../Alerts/Contacts/ContactActivateAlert'), import('../Alerts/Vendors/VendorActivateAlert'),
); );
const ContactInactivateAlert = React.lazy(() => const VendorInactivateAlert = React.lazy(() =>
import('../Alerts/Contacts/ContactInactivateAlert'), import('../Alerts/Vendors/VendorInactivateAlert'),
); );
export default [ export default [
{ name: 'vendor-delete', component: VendorDeleteAlert }, { name: 'vendor-delete', component: VendorDeleteAlert },
{ name: 'contact-activate', component: ContactActivateAlert }, { name: 'vendor-activate', component: VendorActivateAlert },
{ name: 'contact-inactivate', component: ContactInactivateAlert }, { name: 'vendor-inactivate', component: VendorInactivateAlert },
]; ];

View File

@@ -67,15 +67,15 @@ function VendorsTable({
// Handle cancel/confirm inactive. // Handle cancel/confirm inactive.
const handleInactiveVendor = ({ id, contact_service }) => { const handleInactiveVendor = ({ id, contact_service }) => {
openAlert('contact-inactivate', { openAlert('vendor-inactivate', {
contactId: id, vendorId: id,
service: contact_service, service: contact_service,
}); });
}; };
// Handle cancel/confirm activate. // Handle cancel/confirm activate.
const handleActivateVendor = ({ id, contact_service }) => { const handleActivateVendor = ({ id, contact_service }) => {
openAlert('contact-activate', { contactId: id, service: contact_service }); openAlert('vendor-activate', { vendorId: id, service: contact_service });
}; };
// Handle click delete vendor. // Handle click delete vendor.

View File

@@ -2,6 +2,7 @@ import { useQueryClient, useMutation } from 'react-query';
import { useRequestQuery } from '../useQueryRequest'; import { useRequestQuery } from '../useQueryRequest';
import { transformPagination } from 'utils'; import { transformPagination } from 'utils';
import useApiRequest from '../useRequest'; import useApiRequest from '../useRequest';
import { useRequestPdf } from '../utils';
import t from './types'; import t from './types';
const commonInvalidateQueries = (queryClient) => { const commonInvalidateQueries = (queryClient) => {
@@ -341,3 +342,10 @@ export function useRefundCreditTransaction(id, props, requestProps) {
}, },
); );
} }
/**
* Retrieve the credit note pdf document data,
*/
export function usePdfCreditNote(creditNoteId) {
return useRequestPdf(`sales/credit_notes/${creditNoteId}`);
}

View File

@@ -304,12 +304,11 @@ export function useCustomerBalanceSummaryReport(query, props) {
}, },
{ {
select: (res) => ({ select: (res) => ({
columns: res.data.columns,
query: res.data.query, query: res.data.query,
tableRows: res.data.table.rows, table: res.data.table,
}), }),
defaultData: { defaultData: {
tableRows: [], table: {},
query: {}, query: {},
}, },
...props, ...props,
@@ -334,12 +333,11 @@ export function useVendorsBalanceSummaryReport(query, props) {
{ {
select: (res) => ({ select: (res) => ({
columns: res.data.columns,
query: res.data.query, query: res.data.query,
tableRows: res.data.table.data, table: res.data.table,
}), }),
defaultData: { defaultData: {
tableRows: [], table: {},
query: {}, query: {},
}, },
...props, ...props,

View File

@@ -48,6 +48,10 @@ export function useCreateInvoice(props) {
// Invalidate invoice customer. // Invalidate invoice customer.
queryClient.invalidateQueries([t.CUSTOMER, values.customer_id]); queryClient.invalidateQueries([t.CUSTOMER, values.customer_id]);
// Invalidate estimates.
queryClient.invalidateQueries(t.SALE_ESTIMATES);
queryClient.invalidateQueries(t.SALE_ESTIMATE);
// Common invalidate queries. // Common invalidate queries.
commonInvalidateQueries(queryClient); commonInvalidateQueries(queryClient);
}, },
@@ -92,6 +96,10 @@ export function useDeleteInvoice(props) {
// Invalidate specific invoice. // Invalidate specific invoice.
queryClient.invalidateQueries([t.SALE_INVOICE, id]); queryClient.invalidateQueries([t.SALE_INVOICE, id]);
// Invalidate estimates.
queryClient.invalidateQueries(t.SALE_ESTIMATES);
queryClient.invalidateQueries(t.SALE_ESTIMATE);
// Common invalidate queries. // Common invalidate queries.
commonInvalidateQueries(queryClient); commonInvalidateQueries(queryClient);
}, },

View File

@@ -2,6 +2,8 @@ import { useMutation, useQueryClient } from 'react-query';
import { useRequestQuery } from '../useQueryRequest'; import { useRequestQuery } from '../useQueryRequest';
import useApiRequest from '../useRequest'; import useApiRequest from '../useRequest';
import { transformPagination, saveInvoke } from 'utils'; import { transformPagination, saveInvoke } from 'utils';
import { useRequestPdf } from '../utils';
import t from './types'; import t from './types';
// Common invalidate queries. // Common invalidate queries.
@@ -31,11 +33,11 @@ const commonInvalidateQueries = (client) => {
client.invalidateQueries(t.CREDIT_NOTE); client.invalidateQueries(t.CREDIT_NOTE);
client.invalidateQueries(t.CREDIT_NOTES); client.invalidateQueries(t.CREDIT_NOTES);
// Invalidate reconcile. // Invalidate reconcile.
client.invalidateQueries(t.RECONCILE_CREDIT_NOTE); client.invalidateQueries(t.RECONCILE_CREDIT_NOTE);
client.invalidateQueries(t.RECONCILE_CREDIT_NOTES); client.invalidateQueries(t.RECONCILE_CREDIT_NOTES);
// Invalidate invoices payment transactions. // Invalidate invoices payment transactions.
client.invalidateQueries(t.SALE_INVOICE_PAYMENT_TRANSACTIONS); client.invalidateQueries(t.SALE_INVOICE_PAYMENT_TRANSACTIONS);
}; };
@@ -224,3 +226,10 @@ export function usePaymentReceiveSMSDetail(
}, },
); );
} }
/**
* Retrieve the payment receive pdf document data.
*/
export function usePdfPaymentReceive(paymentReceiveId) {
return useRequestPdf(`sales/payment_receives/${paymentReceiveId}`);
}

View File

@@ -1173,7 +1173,6 @@
"From transaction": "من معاملة", "From transaction": "من معاملة",
"Landed": "Landed", "Landed": "Landed",
"This options allows you to be able to add additional cost eg. freight then allocate cost to the items in your bills.": "يتيح لك هذا الخيار إمكانية إضافة تكلفة إضافية على سبيل المثال اضافة تكلفة الشحن ومن ثم تخصيص التكلفة لفواتير الشراء.", "This options allows you to be able to add additional cost eg. freight then allocate cost to the items in your bills.": "يتيح لك هذا الخيار إمكانية إضافة تكلفة إضافية على سبيل المثال اضافة تكلفة الشحن ومن ثم تخصيص التكلفة لفواتير الشراء.",
"Once your delete this located landed cost, you won't be able to restore it later, Are your sure you want to delete this transaction?": "بمجرد حذف معاملة تحميل التكلفة ، لن تتمكن من استعادتها لاحقًا ، هل أنت متأكد من أنك تريد حذف هذه المعاملة؟",
"journal_entries": "القيود", "journal_entries": "القيود",
"contact": "جهة الاتصال", "contact": "جهة الاتصال",
"invoice_details": "تفاصيل الفاتورة", "invoice_details": "تفاصيل الفاتورة",
@@ -1384,7 +1383,7 @@
"filter.value": "قيمة", "filter.value": "قيمة",
"payment_made.empty_status.title": "المنشأة لم تدفع اي اموال إلي الموردين ، إلي حد الأن!.", "payment_made.empty_status.title": "المنشأة لم تدفع اي اموال إلي الموردين ، إلي حد الأن!.",
"estimate.delete.error.estimate_converted_to_invoice": "لا يمكن حذف عملية عرض اسعار الذي تم تحويلها إلي فاتورة بيع.", "estimate.delete.error.estimate_converted_to_invoice": "لا يمكن حذف عملية عرض اسعار الذي تم تحويلها إلي فاتورة بيع.",
"landed_cost.action.delete.success_message": "The landed cost has been deleted successfully.", "landed_cost.action.delete.success_message": "تم حذف تكلفة اضافية بنجاح. ",
"items.option.only_active": "Only active", "items.option.only_active": "Only active",
"items.option_all_items.hint": "جميع الاصناف ، بما في ذلك تلك الاصناف لديها رصيد صفر.", "items.option_all_items.hint": "جميع الاصناف ، بما في ذلك تلك الاصناف لديها رصيد صفر.",
"items.option_with_transactions": "الاصناف مع معاملات", "items.option_with_transactions": "الاصناف مع معاملات",
@@ -1583,6 +1582,9 @@
"refund": "استرجاع", "refund": "استرجاع",
"landed_cost.dialog.label_select_transaction": "حدد المعاملة ", "landed_cost.dialog.label_select_transaction": "حدد المعاملة ",
"landed_cost.dialog.label_select_transaction_entry": "حدد سطر المعاملة ", "landed_cost.dialog.label_select_transaction_entry": "حدد سطر المعاملة ",
"landed_cost.dialog.label_unallocated_cost_amount":"قيمة التكلفة غير المحملة:",
"landed_cost.error.the_total_located_cost_is_bigger_than_the_transaction_line":"إجمالي قيمة التكلفة المحملة أكبر من قيمة سطر المعاملة.",
"landed_cost.once_your_delete_this_located_landed_cost": "بمجرد حذف معاملة تحميل التكلفة ، لن تتمكن من استعادتها لاحقًا ، هل أنت متأكد من أنك تريد حذف هذه المعاملة؟",
"refund_credit_note.dialog.label": "استرجاع اموال", "refund_credit_note.dialog.label": "استرجاع اموال",
"refund_credit_note.dialog.success_message": "تم انشاء معاملة استرجاع الاموال لإشعار الدائن بنجاح.", "refund_credit_note.dialog.success_message": "تم انشاء معاملة استرجاع الاموال لإشعار الدائن بنجاح.",
"refund_credit_note.dialog.refund_date": "تاريخ الاسترجاع", "refund_credit_note.dialog.refund_date": "تاريخ الاسترجاع",
@@ -1757,5 +1759,18 @@
"global_error.you_dont_have_permissions": "ليس لديك صلاحية الوصول إلى هذه الصفحة.", "global_error.you_dont_have_permissions": "ليس لديك صلاحية الوصول إلى هذه الصفحة.",
"global_error.transactions_locked": "تم قفل المعاملات التي تمت قبل {lockedToDate}. ومن ثم لا يمكن القيام بأي عمل.", "global_error.transactions_locked": "تم قفل المعاملات التي تمت قبل {lockedToDate}. ومن ثم لا يمكن القيام بأي عمل.",
"global_error.authorized_user_inactive": "المستخدم المصرح له تم تعطيلة." "global_error.authorized_user_inactive": "المستخدم المصرح له تم تعطيلة.",
}
"vendor.alert.activated_message": "تم تفعيل المورد بنجاح.",
"vendor.alert.are_you_sure_want_to_activate_this_vendor": "هل أنت متأكد أنك تريد تفعيل هذا المورد؟ ستتمكن من تعطيله لاحقًا",
"vendor.alert.inactivated_message": "تم إلغاء تنشيط المورد بنجاح.",
"vendor.alert.are_you_sure_want_to_inactivate_this_vendor":"هل أنت متأكد أنك تريد إلغاء تنشيط هذا المورد؟ ستكون قادرًا على تنشيطه لاحقًا",
"customer.alert.activated_message":"تم تفعيل الزبون بنجاح.",
"customer.alert.are_you_sure_want_to_activate_this_customer": "هل أنت متأكد أنك تريد تفعيل هذا الزبون؟ ستتمكن من تعطيله لاحقًا",
"customer.alert.inactivated_message": "تم إلغاء تنشيط الزبون بنجاح.",
"customer.alert.are_you_sure_want_to_inactivate_this_customer":"هل أنت متأكد أنك تريد إلغاء تنشيط هذا الزبون؟ ستكون قادرًا على تنشيطه لاحقًا",
"credit_note_preview.dialog.title":"معاينة إشعار الدائن PDF",
"payment_receive_preview.dialog.title":"معاينة سند الزبون PDF"
}

View File

@@ -866,7 +866,7 @@
"published_at": "Published at", "published_at": "Published at",
"customers_balance_summary": "Customers Balance Summary", "customers_balance_summary": "Customers Balance Summary",
"vendors_balance_summary": "Vendors Balance Summary", "vendors_balance_summary": "Vendors Balance Summary",
"percentage_of_column": "Percentage", "percentage_of_column": "% of column",
"customers_transactions": "Customers Transactions", "customers_transactions": "Customers Transactions",
"vendors_transactions": "Vendors Transactions", "vendors_transactions": "Vendors Transactions",
"reference_type": "Reference type", "reference_type": "Reference type",
@@ -1145,7 +1145,6 @@
"From transaction": "From transaction", "From transaction": "From transaction",
"landed": "Landed", "landed": "Landed",
"This options allows you to be able to add additional cost eg. freight then allocate cost to the items in your bills.": "This options allows you to be able to add additional cost eg. freight then allocate cost to the items in your bills.", "This options allows you to be able to add additional cost eg. freight then allocate cost to the items in your bills.": "This options allows you to be able to add additional cost eg. freight then allocate cost to the items in your bills.",
"Once your delete this located landed cost, you won't be able to restore it later, Are your sure you want to delete this transaction?": "Once your delete this located landed cost, you won't be able to restore it later, Are your sure you want to delete this transaction?",
"journal_entries": "Journal Entries", "journal_entries": "Journal Entries",
"contact": "Contact", "contact": "Contact",
"invoice_details": "Invoice details", "invoice_details": "Invoice details",
@@ -1193,6 +1192,7 @@
"payment_made.details.payment_number": "Payment #", "payment_made.details.payment_number": "Payment #",
"payment_made.details.subtotal": "Subtotal", "payment_made.details.subtotal": "Subtotal",
"payment_made.details.total": "TOTAL", "payment_made.details.total": "TOTAL",
"payment_made.details.statement": "Statement",
"payment_receive.details.payment_number": "Payment #", "payment_receive.details.payment_number": "Payment #",
"payment_receive.details.total": "TOTAL", "payment_receive.details.total": "TOTAL",
"payment_receive.details.subtotal": "Subtotal", "payment_receive.details.subtotal": "Subtotal",
@@ -1288,11 +1288,11 @@
"inventory_adjustment.details_drawer.title": "Inventory adjustment details", "inventory_adjustment.details_drawer.title": "Inventory adjustment details",
"setup.organization.location": "Location", "setup.organization.location": "Location",
"preferences.general.success_message": "The general preferences has been saved.", "preferences.general.success_message": "The general preferences has been saved.",
"customer.drawer.action.new_invoice": "New invoice", "customer.drawer.action.new_invoice": "New Invoice",
"customer.drawer.action.new_estimate": "New estimate", "customer.drawer.action.new_estimate": "New Estimate",
"customer.drawer.action.new_payment": "New payment", "customer.drawer.action.new_payment": "New Payment",
"customer.drawer.action.new_receipt": "New receipt", "customer.drawer.action.new_receipt": "New Receipt",
"customer.drawer.action.new_transaction": "New transaction", "customer.drawer.action.new_transaction": "New Transaction",
"customer.drawer.action.edit": "Edit", "customer.drawer.action.edit": "Edit",
"customer.drawer.label.outstanding_receivable": "Outstanding receivable", "customer.drawer.label.outstanding_receivable": "Outstanding receivable",
"customer.drawer.label.customer_name": "Customer name", "customer.drawer.label.customer_name": "Customer name",
@@ -1318,9 +1318,9 @@
"vendor.drawer.label.note": "Note", "vendor.drawer.label.note": "Note",
"vendor.drawer.action.edit_vendor": "Edit vendor", "vendor.drawer.action.edit_vendor": "Edit vendor",
"vendor.drawer.action.delete": "Delete", "vendor.drawer.action.delete": "Delete",
"vendor.drawer.action.new_transaction": "New transaction", "vendor.drawer.action.new_transaction": "New Transaction",
"vendor.drawer.action.new_payment": "New payment", "vendor.drawer.action.new_payment": "New Payment",
"vendor.drawer.action.new_invoice": "New purchase invoice", "vendor.drawer.action.new_invoice": "New Purchase Invoice",
"vendor.drawer.action.edit": "Edit", "vendor.drawer.action.edit": "Edit",
"manual_journals.empty_status.description": "Manual journals can be used to record financial transactions manually, used by accountants to work with the ledger.", "manual_journals.empty_status.description": "Manual journals can be used to record financial transactions manually, used by accountants to work with the ledger.",
"manual_journals.empty_status.title": "Create your first journal entries on accounts chart.", "manual_journals.empty_status.title": "Create your first journal entries on accounts chart.",
@@ -1568,6 +1568,9 @@
"refund": "Refund", "refund": "Refund",
"landed_cost.dialog.label_select_transaction": "Select transaction", "landed_cost.dialog.label_select_transaction": "Select transaction",
"landed_cost.dialog.label_select_transaction_entry": "Select transaction entry", "landed_cost.dialog.label_select_transaction_entry": "Select transaction entry",
"landed_cost.dialog.label_unallocated_cost_amount": "Unallocated cost Amount:",
"landed_cost.error.the_total_located_cost_is_bigger_than_the_transaction_line": "The total located cost is bigger than the transaction line.",
"landed_cost.once_your_delete_this_located_landed_cost": "Once your delete this located landed cost, you won't be able to restore it later, Are your sure you want to delete this transaction?",
"refund_credit_note.dialog.label": "Refund Credit Note", "refund_credit_note.dialog.label": "Refund Credit Note",
"refund_credit_note.dialog.success_message": "The customer credit note refund has been created successfully.", "refund_credit_note.dialog.success_message": "The customer credit note refund has been created successfully.",
"refund_credit_note.dialog.refund_date": "Refund date", "refund_credit_note.dialog.refund_date": "Refund date",
@@ -1734,8 +1737,22 @@
"payment_made.drawer.title": "Payment made details {number}", "payment_made.drawer.title": "Payment made details {number}",
"manual_journal.drawer.title": "Manual journal details ({number})", "manual_journal.drawer.title": "Manual journal details ({number})",
"expense.drawer.title": "Expense details", "expense.drawer.title": "Expense details",
"global_error.you_dont_have_permissions": "You do not have permissions to access this page.", "global_error.you_dont_have_permissions": "You do not have permissions to access this page.",
"global_error.transactions_locked": "Transactions before {lockedToDate} has been locked. Hence action cannot be performed.", "global_error.transactions_locked": "Transactions before {lockedToDate} has been locked. Hence action cannot be performed.",
"global_error.authorized_user_inactive": "The authorized user is inactive." "global_error.authorized_user_inactive": "The authorized user is inactive.",
"the_vendor_has_been_inactivated_successfully": "The contact has been inactivated successfully.",
"vendor.alert.activated_message": "The vendor has been activated successfully.",
"vendor.alert.are_you_sure_want_to_inactivate_this_vendor":"Are you sure want to inactivate this vendor? You will to able to activate it later.",
"vendor.alert.inactivated_message": "The vendor has been inactivated successfully.",
"vendor.alert.are_you_sure_want_to_activate_this_vendor": "Are you sure want to activate this vendor? You will to able to inactivate it later.",
"customer.alert.activated_message":"The customer has been activated successfully.",
"customer.alert.are_you_sure_want_to_activate_this_customer": "Are you sure want to activate this customer? You will to able to inactivate it later.",
"customer.alert.inactivated_message": "The customer has been inactivated successfully.",
"customer.alert.are_you_sure_want_to_inactivate_this_customer":"Are you sure want to inactivate this customer? You will to able to activate it later.",
"credit_note_preview.dialog.title":"Credit Note PDF Preview",
"payment_receive_preview.dialog.title":"Payment Receive PDF Preview"
} }