mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-19 22:30:31 +00:00
feat(warehouseTransfer): add warehouseTransfer.
This commit is contained in:
@@ -41,6 +41,7 @@ const CLASSES = {
|
|||||||
PAGE_FORM_EXPENSE: 'page-form--expense',
|
PAGE_FORM_EXPENSE: 'page-form--expense',
|
||||||
PAGE_FORM_CREDIT_NOTE:'page-form--credit-note',
|
PAGE_FORM_CREDIT_NOTE:'page-form--credit-note',
|
||||||
PAGE_FORM_VENDOR_CREDIT_NOTE:'page-form--vendor-credit-note',
|
PAGE_FORM_VENDOR_CREDIT_NOTE:'page-form--vendor-credit-note',
|
||||||
|
PAGE_FORM_WAREHOUSE_TRANSFER:'page-form--warehouse-transfer',
|
||||||
|
|
||||||
FORM_GROUP_LIST_SELECT: 'form-group--select-list',
|
FORM_GROUP_LIST_SELECT: 'form-group--select-list',
|
||||||
|
|
||||||
|
|||||||
@@ -17,5 +17,6 @@ export const DRAWERS = {
|
|||||||
CREDIT_NOTE_DETAIL_DRAWER: 'credit-note-detail-drawer',
|
CREDIT_NOTE_DETAIL_DRAWER: 'credit-note-detail-drawer',
|
||||||
VENDOR_CREDIT_DETAIL_DRAWER: 'vendor-credit-detail-drawer',
|
VENDOR_CREDIT_DETAIL_DRAWER: 'vendor-credit-detail-drawer',
|
||||||
REFUND_CREDIT_NOTE_DETAIL_DRAWER:'refund-credit-detail-drawer',
|
REFUND_CREDIT_NOTE_DETAIL_DRAWER:'refund-credit-detail-drawer',
|
||||||
REFUND_VENDOR_CREDIT_DETAIL_DRAWER:'refund-vendor-detail-drawer'
|
REFUND_VENDOR_CREDIT_DETAIL_DRAWER:'refund-vendor-detail-drawer',
|
||||||
|
WAREHOUSE_TRANSFER_DETAIL_DRAWER:'warehouse-transfer-detail-drawer'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import CreditNoteDetailDrawer from '../containers/Drawers/CreditNoteDetailDrawer
|
|||||||
import VendorCreditDetailDrawer from '../containers/Drawers/VendorCreditDetailDrawer';
|
import VendorCreditDetailDrawer from '../containers/Drawers/VendorCreditDetailDrawer';
|
||||||
import RefundCreditNoteDetailDrawer from '../containers/Drawers/RefundCreditNoteDetailDrawer';
|
import RefundCreditNoteDetailDrawer from '../containers/Drawers/RefundCreditNoteDetailDrawer';
|
||||||
import RefundVendorCreditDetailDrawer from '../containers/Drawers/RefundVendorCreditDetailDrawer';
|
import RefundVendorCreditDetailDrawer from '../containers/Drawers/RefundVendorCreditDetailDrawer';
|
||||||
|
import WarehouseTransferDetailDrawer from '../containers/Drawers/WarehouseTransferDetailDrawer'
|
||||||
|
|
||||||
import { DRAWERS } from 'common/drawers';
|
import { DRAWERS } from 'common/drawers';
|
||||||
|
|
||||||
@@ -59,6 +60,7 @@ export default function DrawersContainer() {
|
|||||||
<RefundVendorCreditDetailDrawer
|
<RefundVendorCreditDetailDrawer
|
||||||
name={DRAWERS.REFUND_VENDOR_CREDIT_DETAIL_DRAWER}
|
name={DRAWERS.REFUND_VENDOR_CREDIT_DETAIL_DRAWER}
|
||||||
/>
|
/>
|
||||||
|
<WarehouseTransferDetailDrawer name={DRAWERS.WAREHOUSE_TRANSFER_DETAIL_DRAWER} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,6 +78,10 @@ export default [
|
|||||||
ability: InventoryAdjustmentAction.View,
|
ability: InventoryAdjustmentAction.View,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
text: <T id={'sidebar_warehouse_transfer'} />,
|
||||||
|
href: '/warehouse-transfers',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
text: <T id={'category_list'} />,
|
text: <T id={'category_list'} />,
|
||||||
href: '/items/categories',
|
href: '/items/categories',
|
||||||
@@ -113,6 +117,10 @@ export default [
|
|||||||
ability: ItemAction.Create,
|
ability: ItemAction.Create,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
text: <T id={'warehouse_transfer.label.new_warehouse_transfer'} />,
|
||||||
|
href: '/warehouse-transfers/new',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
text: <T id={'New service'} />,
|
text: <T id={'New service'} />,
|
||||||
href: '/items/new',
|
href: '/items/new',
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import intl from 'react-intl-universal';
|
||||||
|
import { useSaveSettings } from 'hooks/query';
|
||||||
|
|
||||||
|
import { WarehouseTransferNumberDialogProvider } from './WarehouseTransferNumberDialogProvider';
|
||||||
|
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 { compose } from 'utils';
|
||||||
|
import {
|
||||||
|
transformFormToSettings,
|
||||||
|
transformSettingsToForm,
|
||||||
|
} from 'containers/JournalNumber/utils';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warehouse transfer no dialog content.
|
||||||
|
*/
|
||||||
|
function WarehouseTransferNumberDialogContent({
|
||||||
|
// #ownProps
|
||||||
|
initialValues,
|
||||||
|
onConfirm,
|
||||||
|
|
||||||
|
// #withSettings
|
||||||
|
nextNumber,
|
||||||
|
numberPrefix,
|
||||||
|
autoIncrement,
|
||||||
|
|
||||||
|
// #withDialogActions
|
||||||
|
closeDialog,
|
||||||
|
}) {
|
||||||
|
const { mutateAsync: saveSettings } = useSaveSettings();
|
||||||
|
const [referenceFormValues, setReferenceFormValues] = React.useState(null);
|
||||||
|
|
||||||
|
// Handle the submit form.
|
||||||
|
const handleSubmitForm = (values, { setSubmitting }) => {
|
||||||
|
// Handle the form success.
|
||||||
|
const handleSuccess = () => {
|
||||||
|
setSubmitting(false);
|
||||||
|
closeDialog('warehouse-transfer-no-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, 'warehouse_transfer');
|
||||||
|
|
||||||
|
// Save the settings.
|
||||||
|
saveSettings({ options }).then(handleSuccess).catch(handleErrors);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle the dialog close.
|
||||||
|
const handleClose = () => {
|
||||||
|
closeDialog('warehouse-transfer-no-form');
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle form change.
|
||||||
|
const handleChange = (values) => {
|
||||||
|
setReferenceFormValues(values);
|
||||||
|
};
|
||||||
|
// Description.
|
||||||
|
const description =
|
||||||
|
referenceFormValues?.incrementMode === 'auto'
|
||||||
|
? intl.get('warehouse_transfer.auto_increment.auto')
|
||||||
|
: intl.get('warehouse_transfer.auto_increment.manually');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<WarehouseTransferNumberDialogProvider>
|
||||||
|
<ReferenceNumberForm
|
||||||
|
initialValues={{
|
||||||
|
...transformSettingsToForm({
|
||||||
|
nextNumber,
|
||||||
|
numberPrefix,
|
||||||
|
autoIncrement,
|
||||||
|
}),
|
||||||
|
...initialValues,
|
||||||
|
}}
|
||||||
|
description={description}
|
||||||
|
onSubmit={handleSubmitForm}
|
||||||
|
onClose={handleClose}
|
||||||
|
onChange={handleChange}
|
||||||
|
/>
|
||||||
|
</WarehouseTransferNumberDialogProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default compose(
|
||||||
|
withDialogActions,
|
||||||
|
withSettingsActions,
|
||||||
|
withSettings(({ warehouseTransferSettings }) => ({
|
||||||
|
autoIncrement: warehouseTransferSettings?.autoIncrement,
|
||||||
|
nextNumber: warehouseTransferSettings?.nextNumber,
|
||||||
|
numberPrefix: warehouseTransferSettings?.numberPrefix,
|
||||||
|
})),
|
||||||
|
)(WarehouseTransferNumberDialogContent);
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { DialogContent } from 'components';
|
||||||
|
import { useSettingsWarehouseTransfers } from 'hooks/query';
|
||||||
|
|
||||||
|
const WarehouseTransferNumberDilaogContext = React.createContext();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warehouse transfer number dialog provier.
|
||||||
|
*/
|
||||||
|
function WarehouseTransferNumberDialogProvider({ query, ...props }) {
|
||||||
|
const { isLoading: isSettingsLoading } = useSettingsWarehouseTransfers();
|
||||||
|
|
||||||
|
// Provider payload.
|
||||||
|
const provider = {
|
||||||
|
isSettingsLoading,
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DialogContent isLoading={isSettingsLoading}>
|
||||||
|
<WarehouseTransferNumberDilaogContext.Provider
|
||||||
|
value={provider}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</DialogContent>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const useWarehouseTransferNumberDialogContext = () =>
|
||||||
|
React.useContext(WarehouseTransferNumberDilaogContext);
|
||||||
|
|
||||||
|
export {
|
||||||
|
WarehouseTransferNumberDialogProvider,
|
||||||
|
useWarehouseTransferNumberDialogContext,
|
||||||
|
};
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { FormattedMessage as T } from 'components';
|
||||||
|
import { Dialog, DialogSuspense } from 'components';
|
||||||
|
import withDialogRedux from 'components/DialogReduxConnect';
|
||||||
|
import { compose, saveInvoke } from 'utils';
|
||||||
|
|
||||||
|
const WarehouseTransferNumberDialogContent = React.lazy(() =>
|
||||||
|
import('./WarehouseTransferNumberDialogContent'),
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warehouse transfer number dialog.
|
||||||
|
*/
|
||||||
|
function WarehouseTransferNumberDilaog({
|
||||||
|
dialogName,
|
||||||
|
payload: { initialFormValues },
|
||||||
|
isOpen,
|
||||||
|
onConfirm,
|
||||||
|
}) {
|
||||||
|
const handleConfirm = (values) => {
|
||||||
|
saveInvoke(onConfirm, values);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
title={<T id={'warehouse_transfer_no_settings'} />}
|
||||||
|
name={dialogName}
|
||||||
|
autoFocus={true}
|
||||||
|
canEscapeKeyClose={true}
|
||||||
|
isOpen={isOpen}
|
||||||
|
>
|
||||||
|
<DialogSuspense>
|
||||||
|
<WarehouseTransferNumberDialogContent
|
||||||
|
initialValues={{ ...initialFormValues }}
|
||||||
|
onConfirm={handleConfirm}
|
||||||
|
/>
|
||||||
|
</DialogSuspense>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default compose(withDialogRedux())(WarehouseTransferNumberDilaog);
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Tab } from '@blueprintjs/core';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import intl from 'react-intl-universal';
|
||||||
|
import { DrawerMainTabs } from 'components';
|
||||||
|
|
||||||
|
import WarehouseTransferDetailPanel from './WarehouseTransferDetailPanel';
|
||||||
|
import WarehouseTransferDetailActionsBar from './WarehouseTransferDetailActionsBar';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warehouse transfer view detail.
|
||||||
|
* @returns {React.JSX}
|
||||||
|
*/
|
||||||
|
export default function WarehouseTransferDetail() {
|
||||||
|
return (
|
||||||
|
<WarehouseTransferRoot>
|
||||||
|
<WarehouseTransferDetailActionsBar />
|
||||||
|
<WarehouseTransferDetailsTabs />
|
||||||
|
</WarehouseTransferRoot>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warehouse transfer details tabs.
|
||||||
|
* @returns {React.JSX}
|
||||||
|
*/
|
||||||
|
function WarehouseTransferDetailsTabs() {
|
||||||
|
return (
|
||||||
|
<DrawerMainTabs>
|
||||||
|
<Tab
|
||||||
|
title={intl.get('details')}
|
||||||
|
id={'details'}
|
||||||
|
panel={<WarehouseTransferDetailPanel />}
|
||||||
|
/>
|
||||||
|
</DrawerMainTabs>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const WarehouseTransferRoot = styled.div``;
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { useHistory } from 'react-router-dom';
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
NavbarGroup,
|
||||||
|
Classes,
|
||||||
|
NavbarDivider,
|
||||||
|
Intent,
|
||||||
|
} from '@blueprintjs/core';
|
||||||
|
|
||||||
|
import { useWarehouseDetailDrawerContext } from './WarehouseTransferDetailDrawerProvider';
|
||||||
|
import {
|
||||||
|
DrawerActionsBar,
|
||||||
|
Can,
|
||||||
|
Icon,
|
||||||
|
FormattedMessage as T,
|
||||||
|
If,
|
||||||
|
} from 'components';
|
||||||
|
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||||
|
import withAlertsActions from 'containers/Alert/withAlertActions';
|
||||||
|
import withDrawerActions from 'containers/Drawer/withDrawerActions';
|
||||||
|
|
||||||
|
import { compose } from 'utils';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warehouse transfer detail actions bar.
|
||||||
|
*/
|
||||||
|
function WarehouseTransferDetailActionsBar({
|
||||||
|
// #withAlertsActions
|
||||||
|
openAlert,
|
||||||
|
|
||||||
|
// #withDrawerActions
|
||||||
|
closeDrawer,
|
||||||
|
}) {
|
||||||
|
const history = useHistory();
|
||||||
|
|
||||||
|
// Handle edit warehosue transfer.
|
||||||
|
const handleEditWarehosueTransfer = () => {
|
||||||
|
// history.push(`/warehouse-transfers/${warehouseTransferId}/edit`);
|
||||||
|
closeDrawer('warehouse-transfer-detail-drawer');
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle delete warehouse transfer.
|
||||||
|
const handleDeletetWarehosueTransfer = () => {
|
||||||
|
// openAlert('warehouse-transfer-delete', { warehouseTransferId });
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DrawerActionsBar>
|
||||||
|
<NavbarGroup>
|
||||||
|
<Button
|
||||||
|
className={Classes.MINIMAL}
|
||||||
|
icon={<Icon icon="pen-18" />}
|
||||||
|
text={<T id={'warehouse_transfer.action.edit_warehouse_transfer'} />}
|
||||||
|
onClick={handleEditWarehosueTransfer}
|
||||||
|
/>
|
||||||
|
<NavbarDivider />
|
||||||
|
<Button
|
||||||
|
className={Classes.MINIMAL}
|
||||||
|
icon={<Icon icon={'trash-16'} iconSize={16} />}
|
||||||
|
text={<T id={'delete'} />}
|
||||||
|
intent={Intent.DANGER}
|
||||||
|
onClick={handleDeletetWarehosueTransfer}
|
||||||
|
/>
|
||||||
|
</NavbarGroup>
|
||||||
|
</DrawerActionsBar>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default compose(
|
||||||
|
withDialogActions,
|
||||||
|
withAlertsActions,
|
||||||
|
withDrawerActions,
|
||||||
|
)(WarehouseTransferDetailActionsBar);
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { DrawerBody } from 'components';
|
||||||
|
|
||||||
|
import WarehouseTransferDetail from './WarehouseTransferDetail';
|
||||||
|
import { WarehouseTransferDetailDrawerProvider } from './WarehouseTransferDetailDrawerProvider';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warehouse transfer detail drawer content.
|
||||||
|
*/
|
||||||
|
export default function WarehouseTransferDetailDrawerContent({
|
||||||
|
// #ownProp
|
||||||
|
warehouseTransferId,
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<WarehouseTransferDetailDrawerProvider
|
||||||
|
warehouseTransferId={warehouseTransferId}
|
||||||
|
>
|
||||||
|
<DrawerBody>
|
||||||
|
<WarehouseTransferDetail />
|
||||||
|
</DrawerBody>
|
||||||
|
</WarehouseTransferDetailDrawerProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import intl from 'react-intl-universal';
|
||||||
|
// import {} from 'hooks/query';
|
||||||
|
import { DrawerHeaderContent, DrawerLoading } from 'components';
|
||||||
|
|
||||||
|
const WarehouseTransferDetailDrawerContext = React.createContext();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warehouse transfer detail drawer provider.
|
||||||
|
*/
|
||||||
|
function WarehouseTransferDetailDrawerProvider({
|
||||||
|
warehouseTransferId,
|
||||||
|
...props
|
||||||
|
}) {
|
||||||
|
const provider = {
|
||||||
|
warehouseTransferId,
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DrawerLoading
|
||||||
|
// loading={}
|
||||||
|
>
|
||||||
|
<DrawerHeaderContent
|
||||||
|
name="warehouse-transfer-detail-drawer"
|
||||||
|
title={intl.get('warehouse_transfer.drawer.title', {
|
||||||
|
number: 'W-10',
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
<WarehouseTransferDetailDrawerContext.Provider
|
||||||
|
value={provider}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</DrawerLoading>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const useWarehouseDetailDrawerContext = () =>
|
||||||
|
React.useContext(WarehouseTransferDetailDrawerContext);
|
||||||
|
|
||||||
|
export {
|
||||||
|
WarehouseTransferDetailDrawerProvider,
|
||||||
|
useWarehouseDetailDrawerContext,
|
||||||
|
};
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import intl from 'react-intl-universal';
|
||||||
|
import { defaultTo } from 'lodash';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
import {
|
||||||
|
FormatDate,
|
||||||
|
T,
|
||||||
|
Row,
|
||||||
|
Col,
|
||||||
|
DetailsMenu,
|
||||||
|
DetailItem,
|
||||||
|
CommercialDocHeader,
|
||||||
|
CommercialDocTopHeader,
|
||||||
|
} from 'components';
|
||||||
|
import { useWarehouseDetailDrawerContext } from './WarehouseTransferDetailDrawerProvider';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warehouse transfer details drawer header
|
||||||
|
*/
|
||||||
|
export default function WarehouseTransferDetailHeader() {
|
||||||
|
return (
|
||||||
|
<CommercialDocHeader>
|
||||||
|
<CommercialDocTopHeader>
|
||||||
|
<DetailsMenu>
|
||||||
|
<AmountItem label={intl.get('amount')}>
|
||||||
|
<span class="big-number">'$10'</span>
|
||||||
|
</AmountItem>
|
||||||
|
</DetailsMenu>
|
||||||
|
</CommercialDocTopHeader>
|
||||||
|
<DetailsMenu direction={'horizantal'} minLabelSize={'180px'}>
|
||||||
|
<DetailItem label={intl.get('date')}>
|
||||||
|
{/* <FormatDate value={} /> */}
|
||||||
|
</DetailItem>
|
||||||
|
|
||||||
|
<DetailItem
|
||||||
|
label={intl.get('warehouse_transfer.drawer.label.transfer_number')}
|
||||||
|
// children={}
|
||||||
|
/>
|
||||||
|
<DetailItem
|
||||||
|
label={intl.get('warehouse_transfer.drawer.label.from_warehouse')}
|
||||||
|
// children={}
|
||||||
|
/>
|
||||||
|
<DetailItem
|
||||||
|
label={intl.get('warehouse_transfer.drawer.label.to_warehouse')}
|
||||||
|
// children={}
|
||||||
|
/>
|
||||||
|
<DetailItem
|
||||||
|
label={intl.get('reason')}
|
||||||
|
// children={defaultTo(, '-')}
|
||||||
|
/>
|
||||||
|
</DetailsMenu>
|
||||||
|
</CommercialDocHeader>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const AmountItem = styled(DetailItem)`
|
||||||
|
width: 50%;
|
||||||
|
`;
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { CommercialDocBox } from 'components';
|
||||||
|
|
||||||
|
import WarehouseTransferDetailHeader from './WarehouseTransferDetailHeader';
|
||||||
|
import WarehouseTransferDetailTable from './WarehouseTransferDetailTable';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warehouse transfer details panel.
|
||||||
|
*/
|
||||||
|
export default function WarehouseTransferDetailPanel() {
|
||||||
|
return (
|
||||||
|
<CommercialDocBox>
|
||||||
|
<WarehouseTransferDetailHeader />
|
||||||
|
<WarehouseTransferDetailTable />
|
||||||
|
</CommercialDocBox>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { CommercialDocEntriesTable } from 'components';
|
||||||
|
import { TableStyle } from '../../../common';
|
||||||
|
import { useWarehouseTransferReadOnlyEntriesColumns } from './utils';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warehouse transfer detail table.
|
||||||
|
* @returns {React.JSX}
|
||||||
|
*/
|
||||||
|
export default function WarehouseTransferDetailTable() {
|
||||||
|
// Warehouse transfer entries table columns.
|
||||||
|
const columns = useWarehouseTransferReadOnlyEntriesColumns();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CommercialDocEntriesTable
|
||||||
|
columns={columns}
|
||||||
|
data={[]}
|
||||||
|
styleName={TableStyle.Constrant}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Drawer, DrawerSuspense } from 'components';
|
||||||
|
import withDrawers from 'containers/Drawer/withDrawers';
|
||||||
|
|
||||||
|
import { compose } from 'utils';
|
||||||
|
|
||||||
|
const WarehouseTransferDetailDrawerContent = React.lazy(() =>
|
||||||
|
import('./WarehouseTransferDetailDrawerContent'),
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warehouse transfer detail drawer.
|
||||||
|
*/
|
||||||
|
function WarehouseTransferDetailDrawer({
|
||||||
|
name,
|
||||||
|
// #withDrawer
|
||||||
|
isOpen,
|
||||||
|
payload: { warehouseTransferId },
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<Drawer
|
||||||
|
isOpen={isOpen}
|
||||||
|
name={name}
|
||||||
|
style={{ minWidth: '700px', maxWidth: '900px' }}
|
||||||
|
size={'65%'}
|
||||||
|
>
|
||||||
|
<DrawerSuspense>
|
||||||
|
<WarehouseTransferDetailDrawerContent
|
||||||
|
warehouseTransferId={warehouseTransferId}
|
||||||
|
/>
|
||||||
|
</DrawerSuspense>
|
||||||
|
</Drawer>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default compose(withDrawers())(WarehouseTransferDetailDrawer);
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import intl from 'react-intl-universal';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Icon,
|
||||||
|
FormattedMessage as T,
|
||||||
|
FormatNumberCell,
|
||||||
|
Choose,
|
||||||
|
} from '../../../components';
|
||||||
|
|
||||||
|
export const useWarehouseTransferReadOnlyEntriesColumns = () =>
|
||||||
|
React.useMemo(
|
||||||
|
() => [
|
||||||
|
{
|
||||||
|
Header: intl.get('warehouse_transfer.column.item_name'),
|
||||||
|
accessor: 'item.name',
|
||||||
|
width: 150,
|
||||||
|
className: 'name',
|
||||||
|
disableSortBy: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: intl.get('warehouse_transfer.column.transfer_quantity'),
|
||||||
|
accessor: 'quantity',
|
||||||
|
Cell: FormatNumberCell,
|
||||||
|
width: 100,
|
||||||
|
align: 'right',
|
||||||
|
disableSortBy: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
);
|
||||||
@@ -21,6 +21,7 @@ export default (mapState) => {
|
|||||||
cashflowSetting: state.settings.data.cashflow,
|
cashflowSetting: state.settings.data.cashflow,
|
||||||
creditNoteSettings: state.settings.data.creditNote,
|
creditNoteSettings: state.settings.data.creditNote,
|
||||||
vendorsCreditNoteSetting: state.settings.data.vendorCredit,
|
vendorsCreditNoteSetting: state.settings.data.vendorCredit,
|
||||||
|
warehouseTransferSettings: state.settings.data.warehouseTransfer,
|
||||||
};
|
};
|
||||||
return mapState ? mapState(mapped, state, props) : mapped;
|
return mapState ? mapState(mapped, state, props) : mapped;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { FastField } from 'formik';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import { CLASSES } from 'common/classes';
|
||||||
|
import { useWarehouseTransferFormContext } from './WarehouseTransferFormProvider';
|
||||||
|
import { entriesFieldShouldUpdate } from './utils';
|
||||||
|
import WarehouseTransferFormEntriesTable from './WarehouseTransferFormEntriesTable';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warehouse transafer editor field.
|
||||||
|
*/
|
||||||
|
export default function WarehouseTransferEditorField() {
|
||||||
|
const { items } = useWarehouseTransferFormContext();
|
||||||
|
return (
|
||||||
|
<div className={classNames(CLASSES.PAGE_FORM_BODY)}>
|
||||||
|
<FastField
|
||||||
|
name={'entries'}
|
||||||
|
items={items}
|
||||||
|
// shouldUpdate={entriesFieldShouldUpdate}
|
||||||
|
>
|
||||||
|
{({
|
||||||
|
form: { values, setFieldValue },
|
||||||
|
field: { value },
|
||||||
|
meta: { error, touched },
|
||||||
|
}) => (
|
||||||
|
<WarehouseTransferFormEntriesTable
|
||||||
|
entries={value}
|
||||||
|
onUpdateData={(entries) => {
|
||||||
|
setFieldValue('entries', entries);
|
||||||
|
}}
|
||||||
|
items={items}
|
||||||
|
errors={error}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</FastField>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import intl from 'react-intl-universal';
|
||||||
|
import { Formik, Form } from 'formik';
|
||||||
|
import { Intent } from '@blueprintjs/core';
|
||||||
|
import { useHistory } from 'react-router-dom';
|
||||||
|
import { CLASSES } from 'common/classes';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
import {
|
||||||
|
CreateWarehouseFormSchema,
|
||||||
|
EditWarehouseFormSchema,
|
||||||
|
} from './WarehouseTransferForm.schema';
|
||||||
|
|
||||||
|
import WarehouseTransferFormHeader from './WarehouseTransferFormHeader';
|
||||||
|
import WarehouseTransferEditorField from './WarehouseTransferEditorField';
|
||||||
|
import WarehouseTransferFormFooter from './WarehouseTransferFormFooter';
|
||||||
|
import WarehouseTransferFormDialog from './WarehouseTransferFormDialog';
|
||||||
|
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
||||||
|
|
||||||
|
import { compose, orderingLinesIndexes, transactionNumber } from 'utils';
|
||||||
|
import { defaultWareTransferEntry, defaultWarehouseTransfer } from './utils';
|
||||||
|
|
||||||
|
function WarehouseTransferForm({
|
||||||
|
// #withSettings
|
||||||
|
warehouseTransferNextNumber,
|
||||||
|
warehouseTransferNumberPrefix,
|
||||||
|
warehouseTransferIncrementMode,
|
||||||
|
}) {
|
||||||
|
const history = useHistory();
|
||||||
|
|
||||||
|
// WarehouseTransfer number.
|
||||||
|
const warehouseTransferNumber = transactionNumber(
|
||||||
|
warehouseTransferNumberPrefix,
|
||||||
|
warehouseTransferNextNumber,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Form initial values.
|
||||||
|
const initialValues = React.useMemo(
|
||||||
|
() => ({
|
||||||
|
...defaultWarehouseTransfer,
|
||||||
|
}),
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
// Handles form submit.
|
||||||
|
const handleSubmit = (values, { setSubmitting, setErrors, resetForm }) => {
|
||||||
|
// Transformes the values of the form to request.
|
||||||
|
const form = {};
|
||||||
|
|
||||||
|
// Handle the request success.
|
||||||
|
const onSuccess = () => {};
|
||||||
|
|
||||||
|
// Handle the request error.
|
||||||
|
const onError = ({
|
||||||
|
response: {
|
||||||
|
data: { errors },
|
||||||
|
},
|
||||||
|
}) => {
|
||||||
|
setSubmitting(false);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={classNames(
|
||||||
|
CLASSES.PAGE_FORM,
|
||||||
|
CLASSES.PAGE_FORM_STRIP_STYLE,
|
||||||
|
CLASSES.PAGE_FORM_WAREHOUSE_TRANSFER,
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<Formik
|
||||||
|
validationSchema={
|
||||||
|
true ? CreateWarehouseFormSchema : EditWarehouseFormSchema
|
||||||
|
}
|
||||||
|
initialValues={initialValues}
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
>
|
||||||
|
<Form>
|
||||||
|
<WarehouseTransferFormHeader />
|
||||||
|
<WarehouseTransferEditorField />
|
||||||
|
<WarehouseTransferFormFooter />
|
||||||
|
<WarehouseTransferFormDialog />
|
||||||
|
</Form>
|
||||||
|
</Formik>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default compose(withDashboardActions)(WarehouseTransferForm);
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import * as Yup from 'yup';
|
||||||
|
import intl from 'react-intl-universal';
|
||||||
|
import { DATATYPES_LENGTH } from 'common/dataTypes';
|
||||||
|
|
||||||
|
const Schema = Yup.object().shape({
|
||||||
|
date: Yup.date().required().label(intl.get('date')),
|
||||||
|
transfer_number: Yup.string()
|
||||||
|
.max(DATATYPES_LENGTH.STRING)
|
||||||
|
.label(intl.get('transfer_number')),
|
||||||
|
from_warehouse: Yup.number().required().label(intl.get('from_warehouse')),
|
||||||
|
to_warehouse: Yup.number().required().label(intl.get('from_warehouse')),
|
||||||
|
reason: Yup.string()
|
||||||
|
.trim()
|
||||||
|
.min(1)
|
||||||
|
.max(DATATYPES_LENGTH.STRING)
|
||||||
|
.label(intl.get('reason')),
|
||||||
|
entries: Yup.array().of(
|
||||||
|
Yup.object().shape({
|
||||||
|
item_id: Yup.number().nullable(),
|
||||||
|
source_warehouse: Yup.number().nullable(),
|
||||||
|
destination_warehouse: Yup.number().nullable(),
|
||||||
|
quantity: Yup.number().nullable().max(DATATYPES_LENGTH.INT_10),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const CreateWarehouseFormSchema = Schema;
|
||||||
|
export const EditWarehouseFormSchema = Schema;
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import WarehouseTransferNumberDialog from '../../Dialogs/WarehouseTransferNumberDialog';
|
||||||
|
import { useFormikContext } from 'formik';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warehouse transfer form dialog.
|
||||||
|
*/
|
||||||
|
export default function WarehouseTransferFormDialog() {
|
||||||
|
// Update the form once the credit number form submit confirm.
|
||||||
|
const handleWarehouseNumberFormConfirm = ({ incrementNumber, manually }) => {
|
||||||
|
setFieldValue('transfer_no', incrementNumber || '');
|
||||||
|
setFieldValue('transfer_no_manually', manually);
|
||||||
|
};
|
||||||
|
const { setFieldValue } = useFormikContext();
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<WarehouseTransferNumberDialog
|
||||||
|
dialogName={'warehouse-transfer-no-form'}
|
||||||
|
onConfirm={handleWarehouseNumberFormConfirm}
|
||||||
|
/>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { useWarehouseTransferTableColumns } from '../utils';
|
||||||
|
import { DataTableEditable } from 'components';
|
||||||
|
import { compose, saveInvoke, updateTableCell } from 'utils';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warehouse transfer form entries table.
|
||||||
|
*/
|
||||||
|
export default function WarehouseTransferFormEntriesTable({
|
||||||
|
// #ownProps
|
||||||
|
items,
|
||||||
|
entries,
|
||||||
|
onUpdateData,
|
||||||
|
errors,
|
||||||
|
}) {
|
||||||
|
// Retrieve the warehouse transfer table columns.
|
||||||
|
const columns = useWarehouseTransferTableColumns();
|
||||||
|
|
||||||
|
// Handle update data.
|
||||||
|
const handleUpdateData = React.useCallback(
|
||||||
|
(rowIndex, columnId, value) => {
|
||||||
|
const newRows = compose(updateTableCell(rowIndex, columnId, value))(
|
||||||
|
entries,
|
||||||
|
);
|
||||||
|
onUpdateData(newRows);
|
||||||
|
},
|
||||||
|
[onUpdateData, entries],
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DataTableEditable
|
||||||
|
columns={columns}
|
||||||
|
data={entries}
|
||||||
|
payload={{
|
||||||
|
items,
|
||||||
|
errors: errors || [],
|
||||||
|
updateData: handleUpdateData,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import { FormGroup, TextArea } from '@blueprintjs/core';
|
||||||
|
import { FormattedMessage as T } from 'components';
|
||||||
|
import { FastField, ErrorMessage } from 'formik';
|
||||||
|
import { Row, Col, Postbox } from 'components';
|
||||||
|
import { CLASSES } from 'common/classes';
|
||||||
|
import { inputIntent } from 'utils';
|
||||||
|
|
||||||
|
export default function WarehouseTransferFormFooter() {
|
||||||
|
return (
|
||||||
|
<div className={classNames(CLASSES.PAGE_FORM_FOOTER)}>
|
||||||
|
<Postbox
|
||||||
|
title={<T id={'warehouse_transfer.label.warehouse_transfer_detail'} />}
|
||||||
|
defaultOpen={false}
|
||||||
|
>
|
||||||
|
<Row>
|
||||||
|
<Col md={8}>
|
||||||
|
{/*------------ reason -----------*/}
|
||||||
|
<FastField name={'reason'}>
|
||||||
|
{({ field, meta: { error, touched } }) => (
|
||||||
|
<FormGroup
|
||||||
|
label={<T id={'reason'} />}
|
||||||
|
className={'form-group--reason'}
|
||||||
|
intent={inputIntent({ error, touched })}
|
||||||
|
helperText={<ErrorMessage name={'reason'} />}
|
||||||
|
>
|
||||||
|
<TextArea
|
||||||
|
growVertically={true}
|
||||||
|
large={true}
|
||||||
|
intent={inputIntent({ error, touched })}
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
)}
|
||||||
|
</FastField>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Postbox>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import { useFormikContext } from 'formik';
|
||||||
|
import intl from 'react-intl-universal';
|
||||||
|
import { CLASSES } from 'common/classes';
|
||||||
|
|
||||||
|
import WarehouseTransferFormHeaderFields from './WarehouseTransferFormHeaderFields';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warehose transfer form header section.
|
||||||
|
*/
|
||||||
|
function WarehouseTransferFormHeader() {
|
||||||
|
return (
|
||||||
|
<div className={classNames(CLASSES.PAGE_FORM_HEADER)}>
|
||||||
|
<WarehouseTransferFormHeaderFields />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default WarehouseTransferFormHeader;
|
||||||
@@ -0,0 +1,212 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
FormGroup,
|
||||||
|
InputGroup,
|
||||||
|
TextArea,
|
||||||
|
Position,
|
||||||
|
ControlGroup,
|
||||||
|
} from '@blueprintjs/core';
|
||||||
|
import { DateInput } from '@blueprintjs/datetime';
|
||||||
|
import { FastField, Field, ErrorMessage } from 'formik';
|
||||||
|
import { FormattedMessage as T } from 'components';
|
||||||
|
import { momentFormatter, compose, tansformDateValue } from 'utils';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
import { CLASSES } from 'common/classes';
|
||||||
|
import {
|
||||||
|
AccountsSelectList,
|
||||||
|
FieldRequiredHint,
|
||||||
|
Icon,
|
||||||
|
InputPrependButton,
|
||||||
|
} from 'components';
|
||||||
|
import { inputIntent, handleDateChange } from 'utils';
|
||||||
|
import { useWarehouseTransferFormContext } from './WarehouseTransferFormProvider';
|
||||||
|
import { useObserveTransferNoSettings } from './utils';
|
||||||
|
import withSettings from 'containers/Settings/withSettings';
|
||||||
|
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warehouse transfer form header fields.
|
||||||
|
*/
|
||||||
|
function WarehouseTransferFormHeaderFields({
|
||||||
|
// #withDialogActions
|
||||||
|
openDialog,
|
||||||
|
|
||||||
|
// #withSettings
|
||||||
|
warehouseTransferAutoIncrement,
|
||||||
|
warehouseTransferNextNumber,
|
||||||
|
warehouseTransferNumberPrefix,
|
||||||
|
}) {
|
||||||
|
const { accounts } = useWarehouseTransferFormContext();
|
||||||
|
|
||||||
|
// Handle warehouse transfer number changing.
|
||||||
|
const handleTransferNumberChange = () => {
|
||||||
|
openDialog('warehouse-transfer-no-form');
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle transfer no. field blur.
|
||||||
|
const handleTransferNoBlur = (form, field) => (event) => {
|
||||||
|
const newValue = event.target.value;
|
||||||
|
|
||||||
|
if (field.value !== newValue && warehouseTransferAutoIncrement) {
|
||||||
|
openDialog('warehouse-transfer-no-form', {
|
||||||
|
initialFormValues: {
|
||||||
|
manualTransactionNo: newValue,
|
||||||
|
incrementMode: 'manual-transaction',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Syncs transfer number settings with form.
|
||||||
|
useObserveTransferNoSettings(
|
||||||
|
warehouseTransferNumberPrefix,
|
||||||
|
warehouseTransferNextNumber,
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
|
||||||
|
{/* ----------- Date ----------- */}
|
||||||
|
<FastField name={'date'}>
|
||||||
|
{({ form, field: { value }, meta: { error, touched } }) => (
|
||||||
|
<FormGroup
|
||||||
|
label={<T id={'date'} />}
|
||||||
|
inline={true}
|
||||||
|
labelInfo={<FieldRequiredHint />}
|
||||||
|
className={classNames('form-group--date', CLASSES.FILL)}
|
||||||
|
intent={inputIntent({ error, touched })}
|
||||||
|
helperText={<ErrorMessage name="date" />}
|
||||||
|
>
|
||||||
|
<DateInput
|
||||||
|
{...momentFormatter('YYYY/MM/DD')}
|
||||||
|
value={tansformDateValue(value)}
|
||||||
|
onChange={handleDateChange((formattedDate) => {
|
||||||
|
form.setFieldValue('date', formattedDate);
|
||||||
|
})}
|
||||||
|
popoverProps={{ position: Position.BOTTOM_LEFT, minimal: true }}
|
||||||
|
inputProps={{
|
||||||
|
leftIcon: <Icon icon={'date-range'} />,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
)}
|
||||||
|
</FastField>
|
||||||
|
{/* ----------- Transfer number ----------- */}
|
||||||
|
<Field name={'transfer_number'}>
|
||||||
|
{({ form, field, meta: { error, touched } }) => (
|
||||||
|
<FormGroup
|
||||||
|
label={<T id={'warehouse_transfer.label.transfer_no'} />}
|
||||||
|
labelInfo={<FieldRequiredHint />}
|
||||||
|
inline={true}
|
||||||
|
className={classNames('form-group--transfer-no', CLASSES.FILL)}
|
||||||
|
intent={inputIntent({ error, touched })}
|
||||||
|
helperText={<ErrorMessage name="transfer_number" />}
|
||||||
|
>
|
||||||
|
<ControlGroup fill={true}>
|
||||||
|
<InputGroup
|
||||||
|
minimal={true}
|
||||||
|
value={field.value}
|
||||||
|
asyncControl={true}
|
||||||
|
onBlur={handleTransferNoBlur(form, field)}
|
||||||
|
/>
|
||||||
|
<InputPrependButton
|
||||||
|
buttonProps={{
|
||||||
|
onClick: handleTransferNumberChange,
|
||||||
|
icon: <Icon icon={'settings-18'} />,
|
||||||
|
}}
|
||||||
|
tooltip={true}
|
||||||
|
tooltipProps={{
|
||||||
|
content: (
|
||||||
|
<T
|
||||||
|
id={
|
||||||
|
'warehouse_transfer.setting_your_auto_generated_transfer_no'
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
position: Position.BOTTOM_LEFT,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</ControlGroup>
|
||||||
|
</FormGroup>
|
||||||
|
)}
|
||||||
|
</Field>
|
||||||
|
{/* ----------- Form Warehouse ----------- */}
|
||||||
|
<FastField name={'form_warehouse'} accounts={accounts}>
|
||||||
|
{({ form, field: { value }, meta: { error, touched } }) => (
|
||||||
|
<FormGroup
|
||||||
|
label={<T id={'warehouse_transfer.label.form_warehouse'} />}
|
||||||
|
className={classNames(
|
||||||
|
'form-group--warehouse-transfer',
|
||||||
|
CLASSES.FILL,
|
||||||
|
)}
|
||||||
|
inline={true}
|
||||||
|
labelInfo={<FieldRequiredHint />}
|
||||||
|
intent={inputIntent({ error, touched })}
|
||||||
|
helperText={<ErrorMessage name={'form_warehouse'} />}
|
||||||
|
>
|
||||||
|
<AccountsSelectList
|
||||||
|
accounts={accounts}
|
||||||
|
onAccountSelected={(account) => {
|
||||||
|
form.setFieldValue('form_warehouse', account.id);
|
||||||
|
}}
|
||||||
|
defaultSelectText={'Select Warehouse Transfer'}
|
||||||
|
selectedAccountId={value}
|
||||||
|
popoverFill={true}
|
||||||
|
allowCreate={true}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
)}
|
||||||
|
</FastField>
|
||||||
|
{/* ----------- To Warehouse ----------- */}
|
||||||
|
<FastField name={'to_warehouse'} accounts={accounts}>
|
||||||
|
{({ form, field: { value }, meta: { error, touched } }) => (
|
||||||
|
<FormGroup
|
||||||
|
label={<T id={'warehouse_transfer.label.to_warehouse'} />}
|
||||||
|
className={classNames(
|
||||||
|
'form-group--warehouse-transfer',
|
||||||
|
CLASSES.FILL,
|
||||||
|
)}
|
||||||
|
inline={true}
|
||||||
|
labelInfo={<FieldRequiredHint />}
|
||||||
|
intent={inputIntent({ error, touched })}
|
||||||
|
helperText={<ErrorMessage name={'to_warehouse'} />}
|
||||||
|
>
|
||||||
|
<AccountsSelectList
|
||||||
|
accounts={accounts}
|
||||||
|
onAccountSelected={(account) => {
|
||||||
|
form.setFieldValue('to_warehouse', account.id);
|
||||||
|
}}
|
||||||
|
defaultSelectText={'Select Warehouse Transfer'}
|
||||||
|
selectedAccountId={value}
|
||||||
|
popoverFill={true}
|
||||||
|
allowCreate={true}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
)}
|
||||||
|
</FastField>
|
||||||
|
{/*------------ reason -----------*/}
|
||||||
|
<FastField name={'reason'}>
|
||||||
|
{({ field, meta: { error, touched } }) => (
|
||||||
|
<FormGroup
|
||||||
|
label={<T id={'reason'} />}
|
||||||
|
className={'form-group--reason'}
|
||||||
|
intent={inputIntent({ error, touched })}
|
||||||
|
inline={true}
|
||||||
|
helperText={<ErrorMessage name={'reason'} />}
|
||||||
|
>
|
||||||
|
<InputGroup minimal={true} {...field} />
|
||||||
|
</FormGroup>
|
||||||
|
)}
|
||||||
|
</FastField>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default compose(
|
||||||
|
withDialogActions,
|
||||||
|
withSettings(({ warehouseTransferSettings }) => ({
|
||||||
|
warehouseTransferAutoIncrement: warehouseTransferSettings?.autoIncrement,
|
||||||
|
warehouseTransferNextNumber: warehouseTransferSettings?.nextNumber,
|
||||||
|
warehouseTransferNumberPrefix: warehouseTransferSettings?.numberPrefix,
|
||||||
|
})),
|
||||||
|
)(WarehouseTransferFormHeaderFields);
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import '../../../style/pages/WarehouseTransfers/PageForm.scss'
|
||||||
|
import WarehouseTransferForm from './WarehouseTransferForm';
|
||||||
|
import { WarehouseTransferFormProvider } from './WarehouseTransferFormProvider';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WarehouseTransfer form page.
|
||||||
|
*/
|
||||||
|
export default function WarehouseTransferFormPage() {
|
||||||
|
return (
|
||||||
|
<WarehouseTransferFormProvider warehouseTransferId={null}>
|
||||||
|
<WarehouseTransferForm />
|
||||||
|
</WarehouseTransferFormProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import DashboardInsider from 'components/Dashboard/DashboardInsider';
|
||||||
|
import { useItems, useAccounts } from 'hooks/query';
|
||||||
|
import { ITEMS_FILTER_ROLES_QUERY } from './utils.js';
|
||||||
|
|
||||||
|
const WarehouseFormContext = React.createContext();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warehouse transfer form provider.
|
||||||
|
*/
|
||||||
|
function WarehouseTransferFormProvider({ warehouseTransferId, ...props }) {
|
||||||
|
// Handle fetch Items data table or list
|
||||||
|
const {
|
||||||
|
data: { items },
|
||||||
|
isFetching: isItemsFetching,
|
||||||
|
isLoading: isItemsLoading,
|
||||||
|
} = useItems({
|
||||||
|
page_size: 10000,
|
||||||
|
stringified_filter_roles: ITEMS_FILTER_ROLES_QUERY,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Fetch accounts list.
|
||||||
|
const { data: accounts, isLoading: isAccountsLoading } = useAccounts();
|
||||||
|
|
||||||
|
// Provider payload.
|
||||||
|
const provider = {
|
||||||
|
items,
|
||||||
|
accounts,
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<DashboardInsider
|
||||||
|
loading={isItemsLoading || isAccountsLoading}
|
||||||
|
name={'warehouseTransfer-form'}
|
||||||
|
>
|
||||||
|
<WarehouseFormContext.Provider value={provider} {...props} />
|
||||||
|
</DashboardInsider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const useWarehouseTransferFormContext = () =>
|
||||||
|
React.useContext(WarehouseFormContext);
|
||||||
|
|
||||||
|
export { WarehouseTransferFormProvider, useWarehouseTransferFormContext };
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import intl from 'react-intl-universal';
|
||||||
|
import clsx from 'classnames';
|
||||||
|
import { useFormikContext } from 'formik';
|
||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
|
import { transactionNumber, repeatValue } from 'utils';
|
||||||
|
|
||||||
|
export const defaultWareTransferEntry = {
|
||||||
|
index: 0,
|
||||||
|
item_id: '',
|
||||||
|
source_warehouse: '100',
|
||||||
|
destination_warehouse: '0',
|
||||||
|
quantity: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const MIN_LINES_NUMBER = 4;
|
||||||
|
|
||||||
|
export const defaultWarehouseTransfer = {
|
||||||
|
date: moment(new Date()).format('YYYY-MM-DD'),
|
||||||
|
transfer_number: '',
|
||||||
|
from_warehouse: '',
|
||||||
|
to_warehouse: '',
|
||||||
|
reason: '',
|
||||||
|
entries: [...repeatValue(defaultWareTransferEntry, MIN_LINES_NUMBER)],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ITEMS_FILTER_ROLES_QUERY = JSON.stringify([
|
||||||
|
{
|
||||||
|
index: 1,
|
||||||
|
fieldKey: 'sellable',
|
||||||
|
value: true,
|
||||||
|
condition: '&&',
|
||||||
|
comparator: 'equals',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: 2,
|
||||||
|
fieldKey: 'active',
|
||||||
|
value: true,
|
||||||
|
condition: '&&',
|
||||||
|
comparator: 'equals',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Syncs transfer no. settings with form.
|
||||||
|
*/
|
||||||
|
export const useObserveTransferNoSettings = (prefix, nextNumber) => {
|
||||||
|
const { setFieldValue } = useFormikContext();
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
const transferNo = transactionNumber(prefix, nextNumber);
|
||||||
|
setFieldValue('transfer_no', transferNo);
|
||||||
|
}, [setFieldValue, prefix, nextNumber]);
|
||||||
|
};
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { useHistory } from 'react-router-dom';
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Classes,
|
||||||
|
NavbarDivider,
|
||||||
|
NavbarGroup,
|
||||||
|
Intent,
|
||||||
|
Alignment,
|
||||||
|
} from '@blueprintjs/core';
|
||||||
|
import {
|
||||||
|
Icon,
|
||||||
|
FormattedMessage as T,
|
||||||
|
AdvancedFilterPopover,
|
||||||
|
DashboardFilterButton,
|
||||||
|
DashboardRowsHeightButton,
|
||||||
|
DashboardActionViewsList,
|
||||||
|
} from 'components';
|
||||||
|
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
|
||||||
|
|
||||||
|
import withSettingsActions from 'containers/Settings/withSettingsActions';
|
||||||
|
|
||||||
|
import { compose } from 'utils';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warehouse Transfers actions bar.
|
||||||
|
*/
|
||||||
|
function WarehouseTransfersActionsBar({
|
||||||
|
// #withSettingsActions
|
||||||
|
addSetting,
|
||||||
|
}) {
|
||||||
|
const history = useHistory();
|
||||||
|
|
||||||
|
// Handle new warehouse transfer button click.
|
||||||
|
const handleClickNewWarehouseTransfer = () => {
|
||||||
|
history.push('/warehouse-transfers/new');
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle click a refresh warehouse transfers
|
||||||
|
const handleRefreshBtnClick = () => {
|
||||||
|
// refresh();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle views tab change.
|
||||||
|
const handleTabChange = (view) => {};
|
||||||
|
|
||||||
|
// Handle table row size change.
|
||||||
|
const handleTableRowSizeChange = (size) => {};
|
||||||
|
return (
|
||||||
|
<DashboardActionsBar>
|
||||||
|
<NavbarGroup>
|
||||||
|
<DashboardActionViewsList
|
||||||
|
resourceName={''}
|
||||||
|
views={[]}
|
||||||
|
onChange={handleTabChange}
|
||||||
|
/>
|
||||||
|
<NavbarDivider />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
className={Classes.MINIMAL}
|
||||||
|
icon={<Icon icon={'plus'} />}
|
||||||
|
text={<T id={'warehouse_transfer.action.new_warehouse_transfer'} />}
|
||||||
|
onClick={handleClickNewWarehouseTransfer}
|
||||||
|
/>
|
||||||
|
<NavbarDivider />
|
||||||
|
<Button
|
||||||
|
className={Classes.MINIMAL}
|
||||||
|
icon={<Icon icon={'print-16'} iconSize={'16'} />}
|
||||||
|
text={<T id={'print'} />}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
className={Classes.MINIMAL}
|
||||||
|
icon={<Icon icon={'file-import-16'} />}
|
||||||
|
text={<T id={'import'} />}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
className={Classes.MINIMAL}
|
||||||
|
icon={<Icon icon={'file-export-16'} iconSize={'16'} />}
|
||||||
|
text={<T id={'export'} />}
|
||||||
|
/>
|
||||||
|
<NavbarDivider />
|
||||||
|
<DashboardRowsHeightButton
|
||||||
|
// initialValue={warehouseTransfersTableSize}
|
||||||
|
// onChange={handleTableRowSizeChange}
|
||||||
|
/>
|
||||||
|
<NavbarDivider />
|
||||||
|
</NavbarGroup>
|
||||||
|
<NavbarGroup align={Alignment.RIGHT}>
|
||||||
|
<Button
|
||||||
|
className={Classes.MINIMAL}
|
||||||
|
icon={<Icon icon="refresh-16" iconSize={14} />}
|
||||||
|
// onClick={handleRefreshBtnClick}
|
||||||
|
/>
|
||||||
|
</NavbarGroup>
|
||||||
|
</DashboardActionsBar>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default compose(withSettingsActions)(WarehouseTransfersActionsBar);
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { useHistory } from 'react-router-dom';
|
||||||
|
|
||||||
|
import WarehouseTransfersEmptyStatus from './WarehouseTransfersEmptyStatus';
|
||||||
|
|
||||||
|
import { DataTable, DashboardContentTable } from 'components';
|
||||||
|
import { TABLES } from 'common/tables';
|
||||||
|
import { useMemorizedColumnsWidths } from 'hooks';
|
||||||
|
|
||||||
|
import TableSkeletonRows from 'components/Datatable/TableSkeletonRows';
|
||||||
|
import TableSkeletonHeader from 'components/Datatable/TableHeaderSkeleton';
|
||||||
|
|
||||||
|
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
||||||
|
import withDrawerActions from 'containers/Drawer/withDrawerActions';
|
||||||
|
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||||
|
import withAlertsActions from 'containers/Alert/withAlertActions';
|
||||||
|
import withSettings from '../../Settings/withSettings';
|
||||||
|
|
||||||
|
import { useWarehouseTransfersTableColumns, ActionsMenu } from './components';
|
||||||
|
import { useWarehouseTranfersListContext } from './WarehouseTransfersListProvider';
|
||||||
|
|
||||||
|
import { compose } from 'utils';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warehouse transfers datatable.
|
||||||
|
*/
|
||||||
|
function WarehouseTransfersDataTable({
|
||||||
|
// #withAlertsActions
|
||||||
|
openAlert,
|
||||||
|
|
||||||
|
// #withDrawerActions
|
||||||
|
openDrawer,
|
||||||
|
|
||||||
|
// #withDialogAction
|
||||||
|
openDialog,
|
||||||
|
}) {
|
||||||
|
const history = useHistory();
|
||||||
|
|
||||||
|
// Warehouse transfers list context.
|
||||||
|
const { isEmptyStatus } = useWarehouseTranfersListContext();
|
||||||
|
|
||||||
|
// Invoices table columns.
|
||||||
|
const columns = useWarehouseTransfersTableColumns();
|
||||||
|
|
||||||
|
// Handle view detail.
|
||||||
|
const handleViewDetailWarehouseTransfer = () => {
|
||||||
|
openDrawer('warehouse-transfer-detail-drawer', {});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle edit warehouse transfer.
|
||||||
|
const handleEditWarehouseTransfer = () => {};
|
||||||
|
|
||||||
|
// Handle delete warehouse transfer.
|
||||||
|
const handleDeleteWarehouseTransfer = () => {};
|
||||||
|
|
||||||
|
// Handle cell click.
|
||||||
|
const handleCellClick = (cell, event) => {};
|
||||||
|
|
||||||
|
// Local storage memorizing columns widths.
|
||||||
|
const [initialColumnsWidths, , handleColumnResizing] =
|
||||||
|
useMemorizedColumnsWidths(TABLES.WAREHOUSETRANSFERS);
|
||||||
|
|
||||||
|
// Handles fetch data once the table state change.
|
||||||
|
const handleDataTableFetchData = React.useCallback(
|
||||||
|
({ pageSize, pageIndex, sortBy }) => {},
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
// Display invoice empty status instead of the table.
|
||||||
|
if (isEmptyStatus) {
|
||||||
|
return <WarehouseTransfersEmptyStatus />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DashboardContentTable>
|
||||||
|
<DataTable
|
||||||
|
columns={columns}
|
||||||
|
data={[]}
|
||||||
|
// loading={}
|
||||||
|
// headerLoading={}
|
||||||
|
// progressBarLoading={}
|
||||||
|
onFetchData={handleDataTableFetchData}
|
||||||
|
manualSortBy={true}
|
||||||
|
selectionColumn={true}
|
||||||
|
noInitialFetch={true}
|
||||||
|
sticky={true}
|
||||||
|
TableLoadingRenderer={TableSkeletonRows}
|
||||||
|
TableHeaderSkeletonRenderer={TableSkeletonHeader}
|
||||||
|
ContextMenu={ActionsMenu}
|
||||||
|
onCellClick={handleCellClick}
|
||||||
|
initialColumnsWidths={initialColumnsWidths}
|
||||||
|
onColumnResizing={handleColumnResizing}
|
||||||
|
// size={invoicesTableSize}
|
||||||
|
payload={{
|
||||||
|
onViewDetails: handleViewDetailWarehouseTransfer,
|
||||||
|
onDelete: handleDeleteWarehouseTransfer,
|
||||||
|
onEdit: handleEditWarehouseTransfer,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</DashboardContentTable>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default compose(
|
||||||
|
withDashboardActions,
|
||||||
|
withAlertsActions,
|
||||||
|
withDrawerActions,
|
||||||
|
withDialogActions,
|
||||||
|
)(WarehouseTransfersDataTable);
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { useHistory } from 'react-router-dom';
|
||||||
|
import { Button, Intent } from '@blueprintjs/core';
|
||||||
|
import { EmptyStatus } from 'components';
|
||||||
|
import { Can, FormattedMessage as T } from 'components';
|
||||||
|
|
||||||
|
export default function WarehouseTransfersEmptyStatus() {
|
||||||
|
const history = useHistory();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<EmptyStatus
|
||||||
|
title={<T id={'the_organization_doesn_t_receive_money_yet'} />}
|
||||||
|
description={<p></p>}
|
||||||
|
action={
|
||||||
|
<>
|
||||||
|
<Button
|
||||||
|
intent={Intent.PRIMARY}
|
||||||
|
large={true}
|
||||||
|
onClick={() => {
|
||||||
|
history.push('/warehouse-transfers/new');
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<T id={'warehouse_transfer.action.new_warehouse_transfer'} />
|
||||||
|
</Button>
|
||||||
|
<Button intent={Intent.NONE} large={true}>
|
||||||
|
<T id={'learn_more'} />
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
// style..
|
||||||
|
import { DashboardPageContent } from 'components';
|
||||||
|
import WarehouseTransfersActionsBar from './WarehouseTransfersActionsBar';
|
||||||
|
|
||||||
|
import WarehouseTransfersViewTabs from './WarehouseTransfersViewTabs';
|
||||||
|
import WarehouseTransfersDataTable from './WarehouseTransfersDataTable';
|
||||||
|
|
||||||
|
import { WarehouseTransfersListProvider } from './WarehouseTransfersListProvider';
|
||||||
|
import { compose } from 'utils';
|
||||||
|
|
||||||
|
function WarehouseTransfersList({}) {
|
||||||
|
return (
|
||||||
|
<WarehouseTransfersListProvider>
|
||||||
|
<WarehouseTransfersActionsBar />
|
||||||
|
<DashboardPageContent>
|
||||||
|
<WarehouseTransfersViewTabs />
|
||||||
|
<WarehouseTransfersDataTable />
|
||||||
|
</DashboardPageContent>
|
||||||
|
</WarehouseTransfersListProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default WarehouseTransfersList;
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { isEmpty } from 'lodash';
|
||||||
|
|
||||||
|
import DashboardInsider from 'components/Dashboard/DashboardInsider';
|
||||||
|
|
||||||
|
const WarehouseTransfersListContext = React.createContext();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WarehouseTransfer data provider
|
||||||
|
*/
|
||||||
|
function WarehouseTransfersListProvider({ ...props }) {
|
||||||
|
// Detarmines the datatable empty status.
|
||||||
|
const isEmptyStatus = false;
|
||||||
|
|
||||||
|
// Provider payload.
|
||||||
|
const provider = {
|
||||||
|
isEmptyStatus,
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<DashboardInsider name={'warehouse-transfers-list'}>
|
||||||
|
<WarehouseTransfersListContext.Provider value={provider} {...props} />
|
||||||
|
</DashboardInsider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const useWarehouseTranfersListContext = () =>
|
||||||
|
React.useContext(WarehouseTransfersListContext);
|
||||||
|
|
||||||
|
export { WarehouseTransfersListProvider, useWarehouseTranfersListContext };
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { useHistory } from 'react-router';
|
||||||
|
import { Alignment, Navbar, NavbarGroup } from '@blueprintjs/core';
|
||||||
|
import { FormattedMessage as T } from 'components';
|
||||||
|
|
||||||
|
import { DashboardViewsTabs } from 'components';
|
||||||
|
|
||||||
|
import { useWarehouseTranfersListContext } from './WarehouseTransfersListProvider';
|
||||||
|
|
||||||
|
import { compose } from 'utils';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warehouse transfer view tabs.
|
||||||
|
*/
|
||||||
|
function WarehouseTransfersViewTabs() {
|
||||||
|
// Handles click a new view tab.
|
||||||
|
const handleClickNewView = () => {};
|
||||||
|
|
||||||
|
// Handles the active tab chaing.
|
||||||
|
const handleTabsChange = (customView) => {};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Navbar className={'navbar--dashboard-views'}>
|
||||||
|
<NavbarGroup align={Alignment.LEFT}>
|
||||||
|
<DashboardViewsTabs
|
||||||
|
customViewId={null}
|
||||||
|
tabs={[]}
|
||||||
|
defaultTabText={<T id={'all'} />}
|
||||||
|
onNewViewTabClick={handleClickNewView}
|
||||||
|
onChange={handleTabsChange}
|
||||||
|
/>
|
||||||
|
</NavbarGroup>
|
||||||
|
</Navbar>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default WarehouseTransfersViewTabs;
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
Intent,
|
||||||
|
Tag,
|
||||||
|
Menu,
|
||||||
|
MenuItem,
|
||||||
|
MenuDivider,
|
||||||
|
ProgressBar,
|
||||||
|
} from '@blueprintjs/core';
|
||||||
|
import intl from 'react-intl-universal';
|
||||||
|
import clsx from 'classnames';
|
||||||
|
import { CLASSES } from '../../../common/classes';
|
||||||
|
import { safeCallback } from 'utils';
|
||||||
|
import {
|
||||||
|
FormatDateCell,
|
||||||
|
FormattedMessage as T,
|
||||||
|
AppToaster,
|
||||||
|
Choose,
|
||||||
|
If,
|
||||||
|
Icon,
|
||||||
|
Can,
|
||||||
|
} from 'components';
|
||||||
|
|
||||||
|
export function ActionsMenu({
|
||||||
|
payload: { onEdit, onDelete, onViewDetails, onPrint },
|
||||||
|
row: { original },
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<Menu>
|
||||||
|
<MenuItem
|
||||||
|
icon={<Icon icon="reader-18" />}
|
||||||
|
text={intl.get('view_details')}
|
||||||
|
onClick={safeCallback(onViewDetails, original)}
|
||||||
|
/>
|
||||||
|
<MenuDivider />
|
||||||
|
<MenuItem
|
||||||
|
icon={<Icon icon="pen-18" />}
|
||||||
|
text={intl.get('warehouse_transfer.action.edit_warehouse_transfer')}
|
||||||
|
onClick={safeCallback(onEdit, original)}
|
||||||
|
/>
|
||||||
|
<MenuDivider />
|
||||||
|
<MenuItem
|
||||||
|
text={intl.get('warehouse_transfer.action.delete_warehouse_transfer')}
|
||||||
|
intent={Intent.DANGER}
|
||||||
|
onClick={safeCallback(onDelete, original)}
|
||||||
|
icon={<Icon icon="trash-16" iconSize={16} />}
|
||||||
|
/>
|
||||||
|
</Menu>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve warehouse transfer table columns.
|
||||||
|
*/
|
||||||
|
export function useWarehouseTransfersTableColumns() {
|
||||||
|
return React.useMemo(
|
||||||
|
() => [
|
||||||
|
{
|
||||||
|
id: 'date',
|
||||||
|
Header: intl.get('date'),
|
||||||
|
accessor: 'date',
|
||||||
|
Cell: FormatDateCell,
|
||||||
|
width: 120,
|
||||||
|
className: 'date',
|
||||||
|
clickable: true,
|
||||||
|
textOverview: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'transfer_no',
|
||||||
|
Header: intl.get('warehouse_transfer.column.transfer_no'),
|
||||||
|
accessor: 'transfer_no',
|
||||||
|
width: 120,
|
||||||
|
className: 'transfer_no',
|
||||||
|
clickable: true,
|
||||||
|
textOverview: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'from_warehouse',
|
||||||
|
Header: intl.get('warehouse_transfer.column.from_warehouse'),
|
||||||
|
accessor: 'from_warehouse',
|
||||||
|
width: 150,
|
||||||
|
clickable: true,
|
||||||
|
textOverview: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'to_warehouse',
|
||||||
|
Header: intl.get('warehouse_transfer.column.to_warehouse'),
|
||||||
|
accessor: 'to_warehouse',
|
||||||
|
width: 150,
|
||||||
|
clickable: true,
|
||||||
|
textOverview: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'reason',
|
||||||
|
Header: intl.get('reason'),
|
||||||
|
accessor: 'reason',
|
||||||
|
className: 'reason',
|
||||||
|
width: 120,
|
||||||
|
clickable: true,
|
||||||
|
textOverview: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'status',
|
||||||
|
Header: intl.get('status'),
|
||||||
|
// accessor: (row) => statusAccessor(row),
|
||||||
|
width: 160,
|
||||||
|
className: 'status',
|
||||||
|
clickable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'created_at',
|
||||||
|
Header: intl.get('created_at'),
|
||||||
|
accessor: 'created_at',
|
||||||
|
Cell: FormatDateCell,
|
||||||
|
width: 120,
|
||||||
|
clickable: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
}
|
||||||
64
src/containers/WarehouseTransfers/utils.js
Normal file
64
src/containers/WarehouseTransfers/utils.js
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { CLASSES } from 'common/classes';
|
||||||
|
import { MoneyFieldCell, FormatDateCell, AppToaster, T } from 'components';
|
||||||
|
import { InputGroupCell, ItemsListCell } from 'components/DataTableCells';
|
||||||
|
|
||||||
|
// Index table cell.
|
||||||
|
export function IndexTableCell({ row: { index } }) {
|
||||||
|
return <span>{index + 1}</span>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves warehouse transfer table columns.
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const useWarehouseTransferTableColumns = () => {
|
||||||
|
return React.useMemo(
|
||||||
|
() => [
|
||||||
|
{
|
||||||
|
Header: '#',
|
||||||
|
accessor: 'index',
|
||||||
|
Cell: IndexTableCell,
|
||||||
|
width: 40,
|
||||||
|
disableResizing: true,
|
||||||
|
disableSortBy: true,
|
||||||
|
className: 'index',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'item_id',
|
||||||
|
Header: 'Item Name',
|
||||||
|
accessor: 'item_id',
|
||||||
|
Cell: ItemsListCell,
|
||||||
|
disableSortBy: true,
|
||||||
|
width: '120',
|
||||||
|
className: 'item',
|
||||||
|
fieldProps: { allowCreate: true },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'source_warehouse',
|
||||||
|
Header: 'Source Warehouse',
|
||||||
|
accessor: 'source_warehouse',
|
||||||
|
disableSortBy: true,
|
||||||
|
align: 'right',
|
||||||
|
width: '100',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'destination_warehouse',
|
||||||
|
Header: 'Destination Warehouse',
|
||||||
|
accessor: 'destination_warehouse',
|
||||||
|
disableSortBy: true,
|
||||||
|
align: 'right',
|
||||||
|
width: '100',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: 'Transfer Quantity',
|
||||||
|
accessor: 'quantity',
|
||||||
|
Cell: MoneyFieldCell,
|
||||||
|
disableSortBy: true,
|
||||||
|
align: 'right',
|
||||||
|
width: '150',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -144,6 +144,17 @@ export function useSettingsVendorCredits(props) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve warehouse transfer settings.
|
||||||
|
*/
|
||||||
|
export function useSettingsWarehouseTransfers(props) {
|
||||||
|
return useSettingsQuery(
|
||||||
|
[t.SETTING, t.SETTING_WAREHOUSE_TRANSFER],
|
||||||
|
{ group: 'warehouse_transfer' },
|
||||||
|
props,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve SMS Notifications settings.
|
* Retrieve SMS Notifications settings.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -146,6 +146,7 @@ const SETTING = {
|
|||||||
SETTING_EDIT_SMS_NOTIFICATION: 'SETTING_EDIT_SMS_NOTIFICATION',
|
SETTING_EDIT_SMS_NOTIFICATION: 'SETTING_EDIT_SMS_NOTIFICATION',
|
||||||
SETTING_CREDIT_NOTES: 'SETTING_CREDIT_NOTES',
|
SETTING_CREDIT_NOTES: 'SETTING_CREDIT_NOTES',
|
||||||
SETTING_VENDOR_CREDITS: 'SETTING_VENDOR_CREDITS',
|
SETTING_VENDOR_CREDITS: 'SETTING_VENDOR_CREDITS',
|
||||||
|
SETTING_WAREHOUSE_TRANSFER: 'SETTING_WAREHOUSE_TRANSFER',
|
||||||
};
|
};
|
||||||
|
|
||||||
const ORGANIZATIONS = {
|
const ORGANIZATIONS = {
|
||||||
@@ -196,6 +197,11 @@ const WAREHOUSES = {
|
|||||||
WAREHOUSES: 'WAREHOUSES',
|
WAREHOUSES: 'WAREHOUSES',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const WAREHOUSE_TRANSFERS = {
|
||||||
|
WAREHOUSE_TRANSFER: 'WAREHOUSE_TRANSFER',
|
||||||
|
WAREHOUSE_TRANSFERS: 'WAREHOUSE_TRANSFERS',
|
||||||
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
...ACCOUNTS,
|
...ACCOUNTS,
|
||||||
...BILLS,
|
...BILLS,
|
||||||
@@ -223,5 +229,6 @@ export default {
|
|||||||
...CREDIT_NOTES,
|
...CREDIT_NOTES,
|
||||||
...VENDOR_CREDIT_NOTES,
|
...VENDOR_CREDIT_NOTES,
|
||||||
...TARNSACTIONS_LOCKING,
|
...TARNSACTIONS_LOCKING,
|
||||||
...WAREHOUSES
|
...WAREHOUSES,
|
||||||
|
...WAREHOUSE_TRANSFERS,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -642,6 +642,7 @@
|
|||||||
"Estimate_number_settings": "Estimate Number Settings",
|
"Estimate_number_settings": "Estimate Number Settings",
|
||||||
"receipt_number_settings": "Receipt Number Settings",
|
"receipt_number_settings": "Receipt Number Settings",
|
||||||
"invoice_number_settings": "Invoice Number Settings",
|
"invoice_number_settings": "Invoice Number Settings",
|
||||||
|
"warehouse_transfer_no_settings": "Transfer Number Settings",
|
||||||
"transaction_number_settings": "Transaction Number Settings",
|
"transaction_number_settings": "Transaction Number Settings",
|
||||||
"receipt_number": "Receipt Number",
|
"receipt_number": "Receipt Number",
|
||||||
"estimate_number_is_not_unqiue": "Estimate number is not unqiue",
|
"estimate_number_is_not_unqiue": "Estimate number is not unqiue",
|
||||||
@@ -1770,9 +1771,6 @@
|
|||||||
"credit_note_preview.dialog.title": "Credit Note PDF Preview",
|
"credit_note_preview.dialog.title": "Credit Note PDF Preview",
|
||||||
"payment_receive_preview.dialog.title": "Payment Receive PDF Preview",
|
"payment_receive_preview.dialog.title": "Payment Receive PDF Preview",
|
||||||
|
|
||||||
"credit_note_preview.dialog.title": "Credit Note PDF Preview",
|
|
||||||
"payment_receive_preview.dialog.title": "Payment Receive PDF Preview",
|
|
||||||
|
|
||||||
"warehouses.label": "Warehouses",
|
"warehouses.label": "Warehouses",
|
||||||
"warehouses.label.new_warehouse": "New Warehouse",
|
"warehouses.label.new_warehouse": "New Warehouse",
|
||||||
"warehouse.dialog.label.new_warehouse": "New Warehouse",
|
"warehouse.dialog.label.new_warehouse": "New Warehouse",
|
||||||
@@ -1795,6 +1793,30 @@
|
|||||||
"warehouses.action.edit_warehouse": "Edit Warehouse",
|
"warehouses.action.edit_warehouse": "Edit Warehouse",
|
||||||
"warehouses.action.delete_warehouse": "Delete Warehouse",
|
"warehouses.action.delete_warehouse": "Delete Warehouse",
|
||||||
"warehouses.action.make_as_parimary": "Mark as Primary",
|
"warehouses.action.make_as_parimary": "Mark as Primary",
|
||||||
"warehouse.alert.delete_message":"The warehouse has been deleted successfully",
|
"warehouse.alert.delete_message": "The warehouse has been deleted successfully",
|
||||||
"warehouse.once_delete_this_warehouse":"Once you delete this warehouse, you won't be able to restore it later. Are you sure you want to delete this warehouse?"
|
"warehouse.once_delete_this_warehouse": "Once you delete this warehouse, you won't be able to restore it later. Are you sure you want to delete this warehouse?",
|
||||||
|
|
||||||
|
"sidebar_warehouse_transfer": "Warehouse Transfers",
|
||||||
|
"warehouse_transfer.label.transfer_no": "Transfer No",
|
||||||
|
"warehouse_transfer.label.form_warehouse": "Form Warehouse",
|
||||||
|
"warehouse_transfer.label.to_warehouse": "To Warehouse",
|
||||||
|
"warehouse_transfer.label.warehouse_transfer_detail": "Warehouse Transfer details",
|
||||||
|
"warehouse_transfer.action.edit_warehouse_transfer": "Edit Warehouse Transfer",
|
||||||
|
"warehouse_transfer.action.delete_warehouse_transfer": "Delete Warehouse Transfer",
|
||||||
|
"warehouse_transfer.action.new_warehouse_transfer": "New Warehouse Transfer",
|
||||||
|
"warehouse_transfer.column.transfer_no": "Transfer #",
|
||||||
|
"warehouse_transfer.column.from_warehouse": "From Warehouse",
|
||||||
|
"warehouse_transfer.column.to_warehouse": "To Warehouse",
|
||||||
|
"warehouse_transfer.column.item_name": "Item Name",
|
||||||
|
"warehouse_transfer.column.transfer_quantity": "Transfer Quantity",
|
||||||
|
"warehouse_transfer.auto_increment.auto": "Your transfer numbers are set on auto-increment mode. Are you sure changing this setting?",
|
||||||
|
"warehouse_transfer.auto_increment.manually": "Your transfer numbers are set on manual mode. Are you sure chaning this settings?",
|
||||||
|
"warehouse_transfer.setting_your_auto_generated_transfer_no": "Setting your auto-generated transfer number",
|
||||||
|
"warehouse_transfer.drawer.title": "Warehouse Transfer details ({number})",
|
||||||
|
"warehouse_transfer.drawer.label.transfer_number": "Transfer Number",
|
||||||
|
"warehouse_transfer.drawer.label.from_warehouse": "From Warehouse",
|
||||||
|
"warehouse_transfer.drawer.label.to_warehouse": "To Warehouse",
|
||||||
|
"warehouse_transfer.label.edit_warehouse_transfer": "Edit Warehouse Transfer",
|
||||||
|
"warehouse_transfer.label.new_warehouse_transfer": "New Warehouse Transfer",
|
||||||
|
"warehouse_transfer.label.warehouse_transfer_list": "Warehouse Transfers List"
|
||||||
}
|
}
|
||||||
@@ -117,6 +117,36 @@ export const getDashboardRoutes = () => [
|
|||||||
defaultSearchResource: RESOURCES_TYPES.ITEM,
|
defaultSearchResource: RESOURCES_TYPES.ITEM,
|
||||||
subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
|
subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
|
||||||
},
|
},
|
||||||
|
// Warehouse Transfer.
|
||||||
|
{
|
||||||
|
path: `/warehouse-transfers/:id/edit`,
|
||||||
|
component: lazy(() => import('containers/Items/ItemFormPage')),
|
||||||
|
name: 'warehouse-transfer-edit',
|
||||||
|
pageTitle: intl.get('warehouse_transfer.label.edit_warehouse_transfer'),
|
||||||
|
backLink: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: `/warehouse-transfers/new`,
|
||||||
|
component: lazy(() =>
|
||||||
|
import(
|
||||||
|
'../containers/WarehouseTransfers/WarehouseTransferForm/WarehouseTransferFormPage'
|
||||||
|
),
|
||||||
|
),
|
||||||
|
name: 'warehouse-transfer-new',
|
||||||
|
pageTitle: intl.get('warehouse_transfer.label.new_warehouse_transfer'),
|
||||||
|
backLink: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: `/warehouse-transfers`,
|
||||||
|
component: lazy(() =>
|
||||||
|
import(
|
||||||
|
'../containers/WarehouseTransfers/WarehouseTransfersLanding/WarehouseTransfersList'
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pageTitle: intl.get('warehouse_transfer.label.warehouse_transfer_list'),
|
||||||
|
// defaultSearchResource: RESOURCES_TYPES.ITEM,
|
||||||
|
// subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
|
||||||
|
},
|
||||||
|
|
||||||
// Financial Reports.
|
// Financial Reports.
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -58,6 +58,9 @@ const initialState = {
|
|||||||
vendorCredit: {
|
vendorCredit: {
|
||||||
tableSize: 'medium',
|
tableSize: 'medium',
|
||||||
},
|
},
|
||||||
|
warehouseTransfer: {
|
||||||
|
tableSize: 'medium',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
50
src/style/pages/WarehouseTransfers/PageForm.scss
Normal file
50
src/style/pages/WarehouseTransfers/PageForm.scss
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
body.page-warehouse-transfer-new,
|
||||||
|
body.page-warehouse-transfer-edit {
|
||||||
|
.dashboard__footer {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard__insider--warehouse-transfer-form {
|
||||||
|
padding-bottom: 64px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-form--warehouse-transfer {
|
||||||
|
$self: '.page-form';
|
||||||
|
|
||||||
|
#{$self}__header {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
&-fields {
|
||||||
|
flex: 1 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bp3-label {
|
||||||
|
min-width: 150px;
|
||||||
|
}
|
||||||
|
.bp3-form-content {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bp3-form-group {
|
||||||
|
&.bp3-inline {
|
||||||
|
max-width: 450px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.col--date {
|
||||||
|
max-width: 435px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#{$self}__footer {
|
||||||
|
.form-group--reason {
|
||||||
|
max-width: 450px;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 60px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user