From 30cd6c8a611dcf26d72eb70226c9a98e8cb34356 Mon Sep 17 00:00:00 2001 From: "a.bouhuolia" Date: Thu, 11 Mar 2021 14:29:38 +0200 Subject: [PATCH] feat(design): fix issues in sidebar design. feat(sales): reference number auto-increment optimizations. fix(payments): payment receive/made statement. --- client/src/common/errors.js | 1 + client/src/common/quickNewOptions.js | 12 +- client/src/components/Authentication.js | 2 +- .../components/Dashboard/DashboardTopbar.js | 9 +- client/src/components/Sidebar/Sidebar.js | 2 +- client/src/components/Sidebar/SidebarHead.js | 62 +++++++- .../Alerts/Items/ItemDeleteAlert.js | 4 +- .../ContactDuplicateForm.js | 3 +- .../EstimateNumberDialogContent.js | 54 ++++--- .../Dialogs/EstimateNumberDialog/index.js | 13 +- .../InvoiceNumberDialogContent.js | 63 ++++---- .../Dialogs/InvoiceNumberDialog/index.js | 24 ++-- .../PaymentReceiveNumberDialogContent.js | 52 ++++--- .../PaymentReceiveNumberDialog/index.js | 8 +- .../ReceiptNumberDialogContent.js | 52 ++++--- .../Dialogs/ReceiptNumberDialog/index.js | 4 +- .../JournalNumber/ReferenceNumberForm.js | 47 +++--- .../ReferenceNumberFormContent.js | 116 +++++++++------ client/src/containers/JournalNumber/utils.js | 36 +++++ .../PaymentForm/PaymentMadeFooter.js | 2 +- .../PaymentMades/PaymentForm/utils.js | 2 +- .../QuickNewDropdown/QuickNewDropdown.js | 32 +++-- .../Estimates/EstimateForm/EstimateForm.js | 27 ++-- .../EstimateForm/EstimateFormDialogs.js | 9 +- .../EstimateForm/EstimateFormHeaderFields.js | 41 +++++- .../EstimateForm/EstimateFormProvider.js | 4 +- .../Sales/Estimates/EstimateForm/utils.js | 18 ++- .../Sales/Invoices/InvoiceForm/InvoiceForm.js | 16 ++- .../InvoiceForm/InvoiceFormDialogs.js | 13 +- .../InvoiceForm/InvoiceFormHeaderFields.js | 51 ++++++- .../InvoiceForm/InvoiceFormProvider.js | 1 + .../Sales/Invoices/InvoiceForm/utils.js | 36 ++++- .../Invoices/InvoicesLanding/components.js | 2 +- .../PaymentReceiveForm/PaymentReceiveForm.js | 44 ++++-- .../PaymentReceiveFormDialogs.js | 9 +- .../PaymentReceiveFormProvider.js | 4 +- .../PaymentReceiveHeaderFields.js | 43 +++++- .../PaymentReceiveForm/utils.js | 20 ++- .../Sales/Receipts/ReceiptForm/ReceiptForm.js | 40 +++--- .../ReceiptForm/ReceiptFormDialogs.js | 9 +- .../ReceiptForm/ReceiptFormHeaderFields.js | 42 ++++-- .../ReceiptForm/ReceiptFormProvider.js | 4 +- .../Sales/Receipts/ReceiptForm/utils.js | 14 +- .../Receipts/ReceiptsLanding/components.js | 5 +- client/src/hooks/query/paymentReceives.js | 2 + client/src/hooks/query/receipts.js | 2 + client/src/static/json/icons.js | 13 ++ client/src/style/App.scss | 4 +- .../DataTable/DataTableEditable.scss | 4 +- .../style/containers/Dashboard/Sidebar.scss | 135 ++++++++++++++---- .../ContactDuplicateDialog.scss | 10 +- .../ReferenceNumber/ReferenceNumber.scss | 19 +++ client/src/style/pages/SaleInvoice/List.scss | 4 +- .../src/style/pages/SaleInvoice/PageForm.scss | 7 +- .../src/style/pages/SaleReceipt/PageForm.scss | 2 +- client/src/utils.js | 2 +- .../controllers/Purchases/BillsPayments.ts | 2 +- server/src/data/options.js | 28 ++-- ...715194514_create_payment_receives_table.js | 2 +- ...00719153909_create_bills_payments_table.js | 2 +- server/src/interfaces/BillPayment.ts | 3 +- server/src/interfaces/PaymentReceive.ts | 6 +- 62 files changed, 921 insertions(+), 378 deletions(-) create mode 100644 client/src/containers/JournalNumber/utils.js create mode 100644 client/src/style/pages/ReferenceNumber/ReferenceNumber.scss diff --git a/client/src/common/errors.js b/client/src/common/errors.js index 14f501a90..5b50b487a 100644 --- a/client/src/common/errors.js +++ b/client/src/common/errors.js @@ -13,4 +13,5 @@ export const ERROR = { // Bills BILL_NUMBER_EXISTS: 'BILL.NUMBER.EXISTS', + SALE_INVOICE_NO_IS_REQUIRED: 'SALE_INVOICE_NO_IS_REQUIRED' }; diff --git a/client/src/common/quickNewOptions.js b/client/src/common/quickNewOptions.js index afcec73ef..88b474dad 100644 --- a/client/src/common/quickNewOptions.js +++ b/client/src/common/quickNewOptions.js @@ -1,8 +1,8 @@ export default [ - { path: 'invoices/new', name: 'Sale invoice', label: 'Ctrl+Shift+I' }, - { path: 'bill//new', name: 'Purchase invoice',label:'Ctrl+Shift+B' }, - { path: 'make-journal-entry', name: 'Manual journal', label: 'Ctrl+Shift+M' }, - { path: 'expenses/new', name: 'Expense', label: 'Ctrl+Shift+X' }, - { path: 'customers/new', name: 'Customer', label: 'Ctrl+Shift+C' }, - { path: 'vendors/new', name: 'Vendor', label: 'Ctrl+Shift+V' }, + { path: 'invoices/new', name: 'Sale invoice' }, + { path: 'bill//new', name: 'Purchase invoice' }, + { path: 'make-journal-entry', name: 'Manual journal' }, + { path: 'expenses/new', name: 'Expense' }, + { path: 'customers/new', name: 'Customer' }, + { path: 'vendors/new', name: 'Vendor' }, ]; diff --git a/client/src/components/Authentication.js b/client/src/components/Authentication.js index aac1b8c83..357486e8f 100644 --- a/client/src/components/Authentication.js +++ b/client/src/components/Authentication.js @@ -14,7 +14,7 @@ function PageFade(props) { } export default function AuthenticationWrapper({ ...rest }) { - const to = { pathname: '/homepage' }; + const to = { pathname: '/' }; const location = useLocation(); const isAuthenticated = useIsAuthenticated(); const locationKey = location.pathname; diff --git a/client/src/components/Dashboard/DashboardTopbar.js b/client/src/components/Dashboard/DashboardTopbar.js index 24eb0396f..f29a3509c 100644 --- a/client/src/components/Dashboard/DashboardTopbar.js +++ b/client/src/components/Dashboard/DashboardTopbar.js @@ -24,6 +24,9 @@ import withSettings from 'containers/Settings/withSettings'; import QuickNewDropdown from 'containers/QuickNewDropdown/QuickNewDropdown'; import { compose } from 'utils'; +/** + * Dashboard topbar. + */ function DashboardTopbar({ // #withDashboard pageTitle, @@ -116,11 +119,7 @@ function DashboardTopbar({
- - {/*
- { organizationName } -
*/} - + diff --git a/client/src/components/Sidebar/Sidebar.js b/client/src/components/Sidebar/Sidebar.js index fa105d573..59966fe62 100644 --- a/client/src/components/Sidebar/Sidebar.js +++ b/client/src/components/Sidebar/Sidebar.js @@ -9,7 +9,7 @@ export default function Sidebar() { return ( - +
diff --git a/client/src/components/Sidebar/SidebarHead.js b/client/src/components/Sidebar/SidebarHead.js index 883553c42..f35d06c35 100644 --- a/client/src/components/Sidebar/SidebarHead.js +++ b/client/src/components/Sidebar/SidebarHead.js @@ -1,12 +1,66 @@ import React from 'react'; -import appMeta from 'config/app'; +import { Button, Popover, Menu, Position } from '@blueprintjs/core'; import Icon from 'components/Icon'; -export default function() { +import { useAuthUser } from 'hooks/state'; +import withSettings from 'containers/Settings/withSettings'; +import { compose, firstLettersArgs } from 'utils'; + +// Popover modifiers. +const POPOVER_MODIFIERS = { + offset: { offset: '20, 8' }, +}; + +/** + * Sideabr head. + */ +function SidebarHead({ + // #withSettings + organizationName, +}) { + const user = useAuthUser(); + return (
+
+ +
+ +
{organizationName}
+
+ + } + position={Position.BOTTOM} + minimal={true} + > + +
+ {user.full_name} +
+
- +
); -}; \ No newline at end of file +} + +export default compose( + withSettings(({ organizationSettings }) => ({ + organizationName: organizationSettings.name, + })), +)(SidebarHead); diff --git a/client/src/containers/Alerts/Items/ItemDeleteAlert.js b/client/src/containers/Alerts/Items/ItemDeleteAlert.js index 553868b04..e8276af35 100644 --- a/client/src/containers/Alerts/Items/ItemDeleteAlert.js +++ b/client/src/containers/Alerts/Items/ItemDeleteAlert.js @@ -30,7 +30,7 @@ function ItemDeleteAlert({ closeAlert, // #withItemsActions - addItemsTableQueries, + setItemsTableState, }) { const { mutateAsync: deleteItem, isLoading } = useDeleteItem(); const { formatMessage } = useIntl(); @@ -51,7 +51,7 @@ function ItemDeleteAlert({ intent: Intent.SUCCESS, }); // Reset to page number one. - addItemsTableQueries({ page: 1 }); + setItemsTableState({ page: 1 }); }) .catch( ({ diff --git a/client/src/containers/Dialogs/ContactDuplicateDialog/ContactDuplicateForm.js b/client/src/containers/Dialogs/ContactDuplicateDialog/ContactDuplicateForm.js index 42e534bf0..87a6c54ed 100644 --- a/client/src/containers/Dialogs/ContactDuplicateDialog/ContactDuplicateForm.js +++ b/client/src/containers/Dialogs/ContactDuplicateDialog/ContactDuplicateForm.js @@ -54,7 +54,7 @@ function ContactDuplicateForm({ {({ isSubmitting }) => (
-

+

@@ -66,7 +66,6 @@ function ContactDuplicateForm({ labelInfo={} intent={inputIntent({ error, touched })} className={'form-group--select-list'} - inline={true} helperText={} > { - const options = optionsMapToArray(values).map((option) => ({ - key: option.key, - ...option, - group: 'sales_estimates', - })); - saveSettingsMutate({ options }) - .then(() => { - setSubmitting(false); - closeDialog('estimate-number-form'); - saveInvoke(onConfirm, values); - }) - .catch(() => { - setSubmitting(false); - }); + // Transformes the form values to settings to save it. + const options = transformFormToSettings(values, 'sales_estimates'); + + const handleSuccess = () => { + setSubmitting(false); + closeDialog('estimate-number-form'); + saveInvoke(onConfirm, values); + }; + const handleErrors = () => { + setSubmitting(false); + }; + if (values.incrementMode === 'manual-transaction') { + handleSuccess(); + return; + } + saveSettingsMutate({ options }).then(handleSuccess).catch(handleErrors); }; const handleClose = useCallback(() => { @@ -50,8 +61,14 @@ function EstimateNumberDialogContent({ return ( @@ -64,5 +81,6 @@ export default compose( withSettings(({ estimatesSettings }) => ({ nextNumber: estimatesSettings?.nextNumber, numberPrefix: estimatesSettings?.numberPrefix, + autoIncrement: estimatesSettings?.autoIncrement, })), )(EstimateNumberDialogContent); diff --git a/client/src/containers/Dialogs/EstimateNumberDialog/index.js b/client/src/containers/Dialogs/EstimateNumberDialog/index.js index 12a152ef8..cf2d5b6ba 100644 --- a/client/src/containers/Dialogs/EstimateNumberDialog/index.js +++ b/client/src/containers/Dialogs/EstimateNumberDialog/index.js @@ -8,12 +8,19 @@ const EstimateNumberDialogContent = lazy(() => import('./EstimateNumberDialogContent'), ); +/** + * Estimate number dialog. + */ function EstimateNumberDialog({ dialogName, - paylaod = { id: null }, + payload: { initialFormValues }, isOpen, onConfirm }) { + const handleConfirm = (values) => { + saveInvoke(onConfirm, values); + }; + return ( saveInvoke(onConfirm, values)}/> + initialValues={{ ...initialFormValues }} + onConfirm={handleConfirm}/> ); diff --git a/client/src/containers/Dialogs/InvoiceNumberDialog/InvoiceNumberDialogContent.js b/client/src/containers/Dialogs/InvoiceNumberDialog/InvoiceNumberDialogContent.js index 344f95749..20baf0ef2 100644 --- a/client/src/containers/Dialogs/InvoiceNumberDialog/InvoiceNumberDialogContent.js +++ b/client/src/containers/Dialogs/InvoiceNumberDialog/InvoiceNumberDialogContent.js @@ -1,4 +1,4 @@ -import React, { useCallback } from 'react'; +import React from 'react'; import { useSaveSettings } from 'hooks/query'; import { InvoiceNumberDialogProvider } from './InvoiceNumberDialogProvider'; @@ -7,57 +7,69 @@ import ReferenceNumberForm from 'containers/JournalNumber/ReferenceNumberForm'; import withDialogActions from 'containers/Dialog/withDialogActions'; import withSettings from 'containers/Settings/withSettings'; import withSettingsActions from 'containers/Settings/withSettingsActions'; -// import withInvoicesActions from 'containers/Sales/Invoice/withInvoiceActions'; - -import { compose, optionsMapToArray } from 'utils'; +import { compose } from 'utils'; +import { + transformFormToSettings, + transformSettingsToForm, +} from 'containers/JournalNumber/utils'; /** * invoice number dialog's content. */ - function InvoiceNumberDialogContent({ // #ownProps + initialValues, onConfirm, // #withSettings nextNumber, numberPrefix, + autoIncrement, // #withDialogActions closeDialog, }) { const { mutateAsync: saveSettings } = useSaveSettings(); + // Handle the submit form. const handleSubmitForm = (values, { setSubmitting }) => { - const { mode, ...autoModeValues } = values; + // Handle the form success. + const handleSuccess = () => { + setSubmitting(false); + closeDialog('invoice-number-form'); + onConfirm(values); + }; + // Handle the form errors. + const handleErrors = () => { + setSubmitting(false); + }; + if (values.incrementMode === 'manual-transaction') { + handleSuccess(); + return; + } + // Transformes the form values to settings to save it. + const options = transformFormToSettings(values, 'sales_invoices'); - const options = optionsMapToArray(autoModeValues).map((option) => ({ - key: option.key, - ...option, - group: 'sales_invoices', - })); - - saveSettings({ options }) - .then(() => { - setSubmitting(false); - closeDialog('invoice-number-form'); - onConfirm(values); - }) - .catch(() => { - setSubmitting(false); - }); + // Save the goddamn settings. + saveSettings({ options }).then(handleSuccess).catch(handleErrors); }; // Handle the dialog close. - const handleClose = useCallback(() => { + const handleClose = () => { closeDialog('invoice-number-form'); - }, [closeDialog]); + }; return ( @@ -71,5 +83,6 @@ export default compose( withSettings(({ invoiceSettings }) => ({ nextNumber: invoiceSettings?.nextNumber, numberPrefix: invoiceSettings?.numberPrefix, + autoIncrement: invoiceSettings?.autoIncrement, })), )(InvoiceNumberDialogContent); diff --git a/client/src/containers/Dialogs/InvoiceNumberDialog/index.js b/client/src/containers/Dialogs/InvoiceNumberDialog/index.js index d707e7248..1e90b6808 100644 --- a/client/src/containers/Dialogs/InvoiceNumberDialog/index.js +++ b/client/src/containers/Dialogs/InvoiceNumberDialog/index.js @@ -8,24 +8,32 @@ const InvoiceNumberDialogContent = lazy(() => import('./InvoiceNumberDialogContent'), ); +/** + * Invoice number dialog. + */ function InvoiceNumberDialog({ dialogName, - payload = { id: null }, + payload: { initialFormValues }, isOpen, onConfirm, }) { + const handleConfirm = (values) => { + saveInvoke(onConfirm, values); + }; + return ( } - name={dialogName} - autoFocus={true} - canEscapeKeyClose={true} - isOpen={isOpen} + title={} + name={dialogName} + autoFocus={true} + canEscapeKeyClose={true} + isOpen={isOpen} > saveInvoke(onConfirm, values)} /> + initialValues={{ ...initialFormValues }} + onConfirm={handleConfirm} + /> ); diff --git a/client/src/containers/Dialogs/PaymentReceiveNumberDialog/PaymentReceiveNumberDialogContent.js b/client/src/containers/Dialogs/PaymentReceiveNumberDialog/PaymentReceiveNumberDialogContent.js index 70f3c0cfa..087d4e5cc 100644 --- a/client/src/containers/Dialogs/PaymentReceiveNumberDialog/PaymentReceiveNumberDialogContent.js +++ b/client/src/containers/Dialogs/PaymentReceiveNumberDialog/PaymentReceiveNumberDialogContent.js @@ -8,43 +8,50 @@ import withDialogActions from 'containers/Dialog/withDialogActions'; import withSettingsActions from 'containers/Settings/withSettingsActions'; import withSettings from 'containers/Settings/withSettings'; -import { saveInvoke, compose, optionsMapToArray } from 'utils'; +import { saveInvoke, compose } from 'utils'; +import { + transformFormToSettings, + transformSettingsToForm, +} from 'containers/JournalNumber/utils'; /** - * payment receive number dialog's content. + * Payment receive number dialog's content. */ - function PaymentNumberDialogContent({ // #withSettings nextNumber, numberPrefix, + autoIncrement, // #withDialogActions closeDialog, // #ownProps onConfirm, + initialValues }) { const { isLoading: isSettingsLoading } = useSettingsPaymentReceives(); const { mutateAsync: saveSettingsMutate } = useSaveSettings(); + // Handle submit form. const handleSubmitForm = (values, { setSubmitting }) => { - const options = optionsMapToArray(values).map((option) => ({ - key: option.key, - ...option, - group: 'payment_receives', - })); + // Transformes the form values to settings to save it. + const options = transformFormToSettings(values, 'payment_receives'); - saveSettingsMutate({ options }) - .then(() => { - setSubmitting(false); - closeDialog('payment-receive-number-form'); + const handleSuccess = () => { + setSubmitting(false); + closeDialog('payment-receive-number-form'); - saveInvoke(onConfirm, values); - }) - .catch(() => { - setSubmitting(false); - }); + saveInvoke(onConfirm, values); + }; + const handleErrors = () => { + setSubmitting(false); + }; + if (values.incrementMode === 'manual-transaction') { + handleSuccess(); + return; + } + saveSettingsMutate({ options }).then(handleSuccess).catch(handleErrors); }; const handleClose = useCallback(() => { @@ -54,8 +61,14 @@ function PaymentNumberDialogContent({ return ( @@ -69,5 +82,6 @@ export default compose( withSettings(({ paymentReceiveSettings }) => ({ nextNumber: paymentReceiveSettings?.nextNumber, numberPrefix: paymentReceiveSettings?.numberPrefix, + autoIncrement: paymentReceiveSettings?.autoIncrement, })), )(PaymentNumberDialogContent); diff --git a/client/src/containers/Dialogs/PaymentReceiveNumberDialog/index.js b/client/src/containers/Dialogs/PaymentReceiveNumberDialog/index.js index cd9026e7f..2019257f7 100644 --- a/client/src/containers/Dialogs/PaymentReceiveNumberDialog/index.js +++ b/client/src/containers/Dialogs/PaymentReceiveNumberDialog/index.js @@ -4,7 +4,7 @@ import { Dialog, DialogSuspense } from 'components'; import withDialogRedux from 'components/DialogReduxConnect'; import { saveInvoke, compose } from 'utils'; -const PaymentReceiveNumbereDialogConetnet = lazy(() => +const PaymentReceiveNumbereDialogContent = lazy(() => import('./PaymentReceiveNumberDialogContent'), ); @@ -13,7 +13,7 @@ const PaymentReceiveNumbereDialogConetnet = lazy(() => */ function PaymentReceiveNumberDialog({ dialogName, - payload = { id: null }, + payload: { initialFormValues }, isOpen, onConfirm }) { @@ -26,8 +26,8 @@ function PaymentReceiveNumberDialog({ isOpen={isOpen} > - saveInvoke(onConfirm, values)} /> diff --git a/client/src/containers/Dialogs/ReceiptNumberDialog/ReceiptNumberDialogContent.js b/client/src/containers/Dialogs/ReceiptNumberDialog/ReceiptNumberDialogContent.js index caa6f7377..f44769030 100644 --- a/client/src/containers/Dialogs/ReceiptNumberDialog/ReceiptNumberDialogContent.js +++ b/client/src/containers/Dialogs/ReceiptNumberDialog/ReceiptNumberDialogContent.js @@ -7,20 +7,25 @@ import ReferenceNumberForm from 'containers/JournalNumber/ReferenceNumberForm'; import withDialogActions from 'containers/Dialog/withDialogActions'; import withSettings from 'containers/Settings/withSettings'; -import { compose, optionsMapToArray, saveInvoke } from 'utils'; +import { compose, saveInvoke } from 'utils'; +import { + transformFormToSettings, + transformSettingsToForm, +} from 'containers/JournalNumber/utils'; /** * Receipt number dialog's content. */ - function ReceiptNumberDialogContent({ // #ownProps - receiptId, + receiptId, onConfirm, + initialValues, // #withSettings nextNumber, numberPrefix, + autoIncrement, // #withDialogActions closeDialog, @@ -28,22 +33,24 @@ function ReceiptNumberDialogContent({ const { isLoading: isSettingsLoading } = useSettingsReceipts(); const { mutateAsync: saveSettingsMutate } = useSaveSettings(); + // Handle the form submit. const handleSubmitForm = (values, { setSubmitting }) => { - const options = optionsMapToArray(values).map((option) => ({ - key: option.key, - ...option, - group: 'sales_receipts', - })); + const handleSuccess = () => { + setSubmitting(false); + closeDialog('receipt-number-form'); + saveInvoke(onConfirm, values); + }; + const handleErrors = () => { + setSubmitting(false); + }; + if (values.incrementMode === 'manual-transaction') { + handleSuccess(); + return; + } + // Transformes the form values to settings to save it. + const options = transformFormToSettings(values, 'sales_receipts'); - saveSettingsMutate({ options }) - .then(() => { - setSubmitting(false); - closeDialog('receipt-number-form'); - saveInvoke(onConfirm, values) - }) - .catch(() => { - setSubmitting(false); - }); + saveSettingsMutate({ options }).then(handleSuccess).catch(handleErrors); }; const handleClose = useCallback(() => { @@ -53,8 +60,14 @@ function ReceiptNumberDialogContent({ return ( @@ -67,5 +80,6 @@ export default compose( withSettings(({ receiptSettings }) => ({ nextNumber: receiptSettings?.nextNumber, numberPrefix: receiptSettings?.numberPrefix, + autoIncrement: receiptSettings?.autoIncrement, })), )(ReceiptNumberDialogContent); diff --git a/client/src/containers/Dialogs/ReceiptNumberDialog/index.js b/client/src/containers/Dialogs/ReceiptNumberDialog/index.js index eac8350ca..36973de77 100644 --- a/client/src/containers/Dialogs/ReceiptNumberDialog/index.js +++ b/client/src/containers/Dialogs/ReceiptNumberDialog/index.js @@ -13,7 +13,7 @@ const ReceiptNumberDialogContent = lazy(() => */ function ReceiptNumberDialog({ dialogName, - paylaod = { id: null }, + payload: { initialFormValues = {} }, isOpen, onConfirm, }) { @@ -31,7 +31,7 @@ function ReceiptNumberDialog({ > diff --git a/client/src/containers/JournalNumber/ReferenceNumberForm.js b/client/src/containers/JournalNumber/ReferenceNumberForm.js index 936b7daa7..bece2a4c1 100644 --- a/client/src/containers/JournalNumber/ReferenceNumberForm.js +++ b/client/src/containers/JournalNumber/ReferenceNumberForm.js @@ -4,8 +4,12 @@ import { Formik, Form } from 'formik'; import { FormattedMessage as T } from 'react-intl'; import { Button, Classes } from '@blueprintjs/core'; import { Intent } from '@blueprintjs/core'; -import { saveInvoke } from 'utils'; + +import 'style/pages/ReferenceNumber/ReferenceNumber.scss'; + import ReferenceNumberFormContent from './ReferenceNumberFormContent'; +import { transformValuesToForm } from './utils'; +import { saveInvoke } from 'utils'; /** * Reference number form. @@ -13,42 +17,45 @@ import ReferenceNumberFormContent from './ReferenceNumberFormContent'; export default function ReferenceNumberForm({ onSubmit, onClose, - initialPrefix, - initialNumber, + initialValues, }) { + // Validation schema. const validationSchema = Yup.object().shape({ - // mode: Yup.string(), - number_prefix: Yup.string(), - next_number: Yup.number(), + incrementMode: Yup.string(), + numberPrefix: Yup.string(), + nextNumber: Yup.number(), + manualTransactionNo: Yup.string(), }); - - const initialValues = useMemo( + // Initial values. + const formInitialValues = useMemo( () => ({ - number_prefix: initialPrefix || '', - next_number: initialNumber || '', + ...initialValues, + incrementMode: + initialValues.incrementMode === 'auto' && + initialValues.manualTransactionNo + ? 'manual-transaction' + : initialValues.incrementMode, }), - [initialPrefix, initialNumber], + [initialValues], ); - - const handleSubmit = (values) => { - debugger; - saveInvoke(onSubmit, values); + // Handle the form submit. + const handleSubmit = (values, methods) => { + const parsed = transformValuesToForm(values); + saveInvoke(onSubmit, { ...parsed, ...values }, methods); }; return ( {({ isSubmitting }) => ( - +

- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce - tincidunt porta quam, + Your invoice numbers are set on auto-increment mod. Are you sure changing this setting?

-
diff --git a/client/src/containers/JournalNumber/ReferenceNumberFormContent.js b/client/src/containers/JournalNumber/ReferenceNumberFormContent.js index 2ced61e9c..8988c7b2b 100644 --- a/client/src/containers/JournalNumber/ReferenceNumberFormContent.js +++ b/client/src/containers/JournalNumber/ReferenceNumberFormContent.js @@ -1,71 +1,103 @@ import React from 'react'; -import { FastField } from 'formik'; +import { FastField, useFormikContext } from 'formik'; import { FormattedMessage as T } from 'react-intl'; import { FormGroup, InputGroup, Radio } from '@blueprintjs/core'; -import { Row, Col, ErrorMessage } from 'components'; +import { If, Row, Col, ErrorMessage } from 'components'; import { inputIntent } from 'utils'; /** * Reference number form content. */ export default function ReferenceNumberFormContent() { + const { values } = useFormikContext(); + return ( <> - + {/* ------------- Auto increment mode ------------- */} + {({ form, field, meta: { error, touched } }) => ( { + form.setFieldValue('incrementMode', 'auto'); + }} + checked={field.value === 'auto'} /> )} - - {/* ------------- Prefix ------------- */} - - - {({ form, field, meta: { error, touched } }) => ( - } - className={'form-group--'} - intent={inputIntent({ error, touched })} - helperText={} - > - + + {/* ------------- Prefix ------------- */} + + + {({ form, field, meta: { error, touched } }) => ( + } + className={'form-group--'} intent={inputIntent({ error, touched })} - {...field} - /> - - )} - - + helperText={} + > + + + )} + + - {/* ------------- Next number ------------- */} - - - {({ form, field, meta: { error, touched } }) => ( - } - className={'form-group--'} - intent={inputIntent({ error, touched })} - helperText={} - > - + + {({ form, field, meta: { error, touched } }) => ( + } + className={'form-group--next-number'} intent={inputIntent({ error, touched })} - {...field} - /> - - )} - - - + helperText={} + > + + + )} + + + + - + {/* ------------- Manual increment mode ------------- */} + {({ form, field, meta: { error, touched } }) => ( - + { + form.setFieldValue('incrementMode', 'manual'); + }} + checked={field.value === 'manual'} + /> )} + + {/* ------------- Transaction manual increment mode ------------- */} + + + {({ form, field, meta: { error, touched } }) => ( + { + form.setFieldValue('incrementMode', 'manual-transaction'); + }} + checked={field.value === 'manual-transaction'} + /> + )} + + ); } diff --git a/client/src/containers/JournalNumber/utils.js b/client/src/containers/JournalNumber/utils.js new file mode 100644 index 000000000..0adc372c6 --- /dev/null +++ b/client/src/containers/JournalNumber/utils.js @@ -0,0 +1,36 @@ +import { + transformToForm, + optionsMapToArray, + transfromToSnakeCase, + transactionNumber, +} from 'utils'; + +export const defaultInvoiceNoSettings = { + nextNumber: '', + numberPrefix: '', + autoIncrement: '', +}; + +export const transformSettingsToForm = (settings) => ({ + ...settings, + incrementMode: settings.autoIncrement === 'true' ? 'auto' : 'manual', +}); + +export const transformFormToSettings = (values, group) => { + const options = transfromToSnakeCase({ + ...transformToForm(values, defaultInvoiceNoSettings), + autoIncrement: values.incrementMode === 'auto', + }); + return optionsMapToArray(options).map((option) => ({ ...option, group })); +}; + +export const transformValuesToForm = (values) => { + const incrementNumber = + values.incrementMode === 'auto' + ? transactionNumber(values.numberPrefix, values.nextNumber) + : values.manualTransactionNo; + + const manually = values.incrementMode === 'auto' ? false : true; + + return { incrementNumber, manually }; +}; diff --git a/client/src/containers/Purchases/PaymentMades/PaymentForm/PaymentMadeFooter.js b/client/src/containers/Purchases/PaymentMades/PaymentForm/PaymentMadeFooter.js index 7b329f07d..ae1156448 100644 --- a/client/src/containers/Purchases/PaymentMades/PaymentForm/PaymentMadeFooter.js +++ b/client/src/containers/Purchases/PaymentMades/PaymentForm/PaymentMadeFooter.js @@ -16,7 +16,7 @@ export default function PaymentMadeFooter() { {/* --------- Statement --------- */} - + {({ form, field, meta: { error, touched } }) => ( } diff --git a/client/src/containers/Purchases/PaymentMades/PaymentForm/utils.js b/client/src/containers/Purchases/PaymentMades/PaymentForm/utils.js index 22732440c..18c3079c2 100644 --- a/client/src/containers/Purchases/PaymentMades/PaymentForm/utils.js +++ b/client/src/containers/Purchases/PaymentMades/PaymentForm/utils.js @@ -21,7 +21,7 @@ export const defaultPaymentMade = { payment_date: moment(new Date()).format('YYYY-MM-DD'), reference: '', payment_number: '', - description: '', + statement: '', entries: [], }; diff --git a/client/src/containers/QuickNewDropdown/QuickNewDropdown.js b/client/src/containers/QuickNewDropdown/QuickNewDropdown.js index 9e82291f1..5a02eefaa 100644 --- a/client/src/containers/QuickNewDropdown/QuickNewDropdown.js +++ b/client/src/containers/QuickNewDropdown/QuickNewDropdown.js @@ -1,10 +1,11 @@ import React from 'react'; -import ListSelect from 'components/ListSelect'; +import { Button, MenuItem } from '@blueprintjs/core'; import { FormattedMessage as T } from 'react-intl'; import { useHistory } from 'react-router-dom'; import { Icon } from 'components'; import { Position } from '@blueprintjs/core'; import quickNewOptions from 'common/quickNewOptions'; +import { Select } from '@blueprintjs/select'; /** * Quick New Dropdown. @@ -12,26 +13,29 @@ import quickNewOptions from 'common/quickNewOptions'; function QuickNewDropdown() { const history = useHistory(); - const handleClickQuickNew = ({path }) => { + const handleClickQuickNew = ({ path }) => { history.push(`/${path}`); }; + const itemRenderer = (item, { handleClick, modifiers, query }) => ( + + ); + return ( - handleClickQuickNew(type)} - textProp={'name'} - labelProp={'label'} - filterable={false} popoverProps={{ minimal: false, position: Position.BOTTOM }} - defaultText={'Select'} - buttonProps={{ - text: , - icon: , - minimal: true, - }} - className={'form-group-quick-new-downDrop'} - /> + className={'form-group--quick-new-downDrop'} + filterable={false} + > +