mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-20 14:50:32 +00:00
feat(Sales & Purchases ): add branch & warehouse.
This commit is contained in:
@@ -12,6 +12,7 @@ import BillFormHeader from './BillFormHeader';
|
|||||||
import BillFloatingActions from './BillFloatingActions';
|
import BillFloatingActions from './BillFloatingActions';
|
||||||
import BillFormFooter from './BillFormFooter';
|
import BillFormFooter from './BillFormFooter';
|
||||||
import BillItemsEntriesEditor from './BillItemsEntriesEditor';
|
import BillItemsEntriesEditor from './BillItemsEntriesEditor';
|
||||||
|
import BillFormTopBar from './BillFormTopBar';
|
||||||
|
|
||||||
import { AppToaster } from 'components';
|
import { AppToaster } from 'components';
|
||||||
|
|
||||||
@@ -125,6 +126,7 @@ function BillForm({
|
|||||||
onSubmit={handleFormSubmit}
|
onSubmit={handleFormSubmit}
|
||||||
>
|
>
|
||||||
<Form>
|
<Form>
|
||||||
|
<BillFormTopBar />
|
||||||
<BillFormHeader />
|
<BillFormHeader />
|
||||||
<BillItemsEntriesEditor />
|
<BillItemsEntriesEditor />
|
||||||
<BillFormFooter />
|
<BillFormFooter />
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ const BillFormSchema = Yup.object().shape({
|
|||||||
.max(DATATYPES_LENGTH.TEXT)
|
.max(DATATYPES_LENGTH.TEXT)
|
||||||
.label(intl.get('note')),
|
.label(intl.get('note')),
|
||||||
open: Yup.boolean(),
|
open: Yup.boolean(),
|
||||||
|
branch_id: Yup.string(),
|
||||||
|
warehouse_id: Yup.string(),
|
||||||
entries: Yup.array().of(
|
entries: Yup.array().of(
|
||||||
Yup.object().shape({
|
Yup.object().shape({
|
||||||
quantity: Yup.number()
|
quantity: Yup.number()
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import {
|
|||||||
useVendors,
|
useVendors,
|
||||||
useItems,
|
useItems,
|
||||||
useBill,
|
useBill,
|
||||||
|
useWarehouses,
|
||||||
|
useBranches,
|
||||||
useSettings,
|
useSettings,
|
||||||
useCreateBill,
|
useCreateBill,
|
||||||
useEditBill,
|
useEditBill,
|
||||||
@@ -14,8 +16,20 @@ const BillFormContext = createContext();
|
|||||||
|
|
||||||
// Filter all purchasable items only.
|
// Filter all purchasable items only.
|
||||||
const stringifiedFilterRoles = JSON.stringify([
|
const stringifiedFilterRoles = JSON.stringify([
|
||||||
{ index: 1, fieldKey: 'purchasable', value: true, condition: '&&', comparator: 'equals' },
|
{
|
||||||
{ index: 2, fieldKey: 'active', value: true, condition: '&&', comparator: 'equals' },
|
index: 1,
|
||||||
|
fieldKey: 'purchasable',
|
||||||
|
value: true,
|
||||||
|
condition: '&&',
|
||||||
|
comparator: 'equals',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: 2,
|
||||||
|
fieldKey: 'active',
|
||||||
|
value: true,
|
||||||
|
condition: '&&',
|
||||||
|
comparator: 'equals',
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -45,6 +59,20 @@ function BillFormProvider({ billId, ...props }) {
|
|||||||
enabled: !!billId,
|
enabled: !!billId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Fetch warehouses list.
|
||||||
|
const {
|
||||||
|
data: warehouses,
|
||||||
|
isLoading: isWarehouesLoading,
|
||||||
|
isSuccess: isWarehousesSuccess,
|
||||||
|
} = useWarehouses();
|
||||||
|
|
||||||
|
// Fetches the branches list.
|
||||||
|
const {
|
||||||
|
data: branches,
|
||||||
|
isLoading: isBranchesLoading,
|
||||||
|
isSuccess: isBranchesSuccess,
|
||||||
|
} = useBranches();
|
||||||
|
|
||||||
// Handle fetching bill settings.
|
// Handle fetching bill settings.
|
||||||
const { isFetching: isSettingLoading } = useSettings();
|
const { isFetching: isSettingLoading } = useSettings();
|
||||||
|
|
||||||
@@ -57,11 +85,16 @@ function BillFormProvider({ billId, ...props }) {
|
|||||||
|
|
||||||
const isNewMode = !billId;
|
const isNewMode = !billId;
|
||||||
|
|
||||||
|
// Determines whether the warehouse and branches are loading.
|
||||||
|
const isFeatureLoading = isWarehouesLoading || isBranchesLoading;
|
||||||
|
|
||||||
const provider = {
|
const provider = {
|
||||||
accounts,
|
accounts,
|
||||||
vendors,
|
vendors,
|
||||||
items,
|
items,
|
||||||
bill,
|
bill,
|
||||||
|
warehouses,
|
||||||
|
branches,
|
||||||
submitPayload,
|
submitPayload,
|
||||||
isNewMode,
|
isNewMode,
|
||||||
|
|
||||||
@@ -70,6 +103,9 @@ function BillFormProvider({ billId, ...props }) {
|
|||||||
isAccountsLoading,
|
isAccountsLoading,
|
||||||
isItemsLoading,
|
isItemsLoading,
|
||||||
isVendorsLoading,
|
isVendorsLoading,
|
||||||
|
isFeatureLoading,
|
||||||
|
isBranchesSuccess,
|
||||||
|
isWarehousesSuccess,
|
||||||
|
|
||||||
createBillMutate,
|
createBillMutate,
|
||||||
editBillMutate,
|
editBillMutate,
|
||||||
|
|||||||
118
src/containers/Purchases/Bills/BillForm/BillFormTopBar.js
Normal file
118
src/containers/Purchases/Bills/BillForm/BillFormTopBar.js
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import intl from 'react-intl-universal';
|
||||||
|
import {
|
||||||
|
Alignment,
|
||||||
|
Navbar,
|
||||||
|
NavbarGroup,
|
||||||
|
NavbarDivider,
|
||||||
|
Button,
|
||||||
|
Classes,
|
||||||
|
} from '@blueprintjs/core';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import {
|
||||||
|
useSetPrimaryBranchToForm,
|
||||||
|
useSetPrimaryWarehouseToForm,
|
||||||
|
} from './utils';
|
||||||
|
import { useFeatureCan } from 'hooks/state';
|
||||||
|
import { Icon, BranchSelect, FeatureCan, WarehouseSelect } from 'components';
|
||||||
|
import { useBillFormContext } from './BillFormProvider';
|
||||||
|
import { Features } from 'common';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bill form topbar .
|
||||||
|
* @returns {JSX.Element}
|
||||||
|
*/
|
||||||
|
export default function BillFormTopBar() {
|
||||||
|
// Features guard.
|
||||||
|
const { featureCan } = useFeatureCan();
|
||||||
|
|
||||||
|
// Sets the primary warehouse to form.
|
||||||
|
useSetPrimaryWarehouseToForm();
|
||||||
|
|
||||||
|
// Sets the primary branch to form.
|
||||||
|
useSetPrimaryBranchToForm();
|
||||||
|
|
||||||
|
// Can't display the navigation bar if warehouses or branches feature is not enabled.
|
||||||
|
if (!featureCan(Features.Warehouses) || !featureCan(Features.Branches)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Navbar className={'navbar--dashboard-topbar'}>
|
||||||
|
<NavbarGroup align={Alignment.LEFT}>
|
||||||
|
<FeatureCan feature={Features.Branches}>
|
||||||
|
<BillFormSelectBranch />
|
||||||
|
</FeatureCan>
|
||||||
|
{featureCan(Features.Warehouses) && featureCan(Features.Branches) && (
|
||||||
|
<NavbarDivider />
|
||||||
|
)}
|
||||||
|
<FeatureCan feature={Features.Warehouses}>
|
||||||
|
<BillFormSelectWarehouse />
|
||||||
|
</FeatureCan>
|
||||||
|
</NavbarGroup>
|
||||||
|
</Navbar>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function BillFormSelectBranch() {
|
||||||
|
// Bill form context.
|
||||||
|
const { branches, isBranchesLoading } = useBillFormContext();
|
||||||
|
|
||||||
|
return isBranchesLoading ? (
|
||||||
|
<DetailsBarSkeletonBase className={Classes.SKELETON} />
|
||||||
|
) : (
|
||||||
|
<BranchSelect
|
||||||
|
name={'branch_id'}
|
||||||
|
branches={branches}
|
||||||
|
input={BillBranchSelectButton}
|
||||||
|
popoverProps={{ minimal: true }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function BillFormSelectWarehouse() {
|
||||||
|
// Bill form context.
|
||||||
|
const { warehouses, isWarehouesLoading } = useBillFormContext();
|
||||||
|
|
||||||
|
return isWarehouesLoading ? (
|
||||||
|
<DetailsBarSkeletonBase className={Classes.SKELETON} />
|
||||||
|
) : (
|
||||||
|
<WarehouseSelect
|
||||||
|
name={'warehouse_id'}
|
||||||
|
warehouses={warehouses}
|
||||||
|
input={BillWarehouseSelectButton}
|
||||||
|
popoverProps={{ minimal: true }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function BillWarehouseSelectButton({ label }) {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
text={intl.get('invoice.warehouse_button.label', { label })}
|
||||||
|
minimal={true}
|
||||||
|
small={true}
|
||||||
|
icon={<Icon icon={'warehouse-16'} iconSize={16} />}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function BillBranchSelectButton({ label }) {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
text={intl.get('invoice.branch_button.label', { label })}
|
||||||
|
minimal={true}
|
||||||
|
small={true}
|
||||||
|
icon={<Icon icon={'branch-16'} iconSize={16} />}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const DetailsBarSkeletonBase = styled.div`
|
||||||
|
letter-spacing: 10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-left: 10px;
|
||||||
|
font-size: 8px;
|
||||||
|
width: 140px;
|
||||||
|
height: 10px;
|
||||||
|
`;
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
|
import React from 'react';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import intl from 'react-intl-universal';
|
import intl from 'react-intl-universal';
|
||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
|
import { first } from 'lodash';
|
||||||
import { Intent } from '@blueprintjs/core';
|
import { Intent } from '@blueprintjs/core';
|
||||||
|
import { useFormikContext } from 'formik';
|
||||||
import { AppToaster } from 'components';
|
import { AppToaster } from 'components';
|
||||||
import {
|
import {
|
||||||
defaultFastFieldShouldUpdate,
|
defaultFastFieldShouldUpdate,
|
||||||
@@ -14,6 +17,7 @@ import {
|
|||||||
ensureEntriesHaveEmptyLine,
|
ensureEntriesHaveEmptyLine,
|
||||||
} from 'containers/Entries/utils';
|
} from 'containers/Entries/utils';
|
||||||
import { isLandedCostDisabled } from '../../../Entries/utils';
|
import { isLandedCostDisabled } from '../../../Entries/utils';
|
||||||
|
import { useBillFormContext } from './BillFormProvider';
|
||||||
|
|
||||||
export const MIN_LINES_NUMBER = 4;
|
export const MIN_LINES_NUMBER = 4;
|
||||||
|
|
||||||
@@ -38,6 +42,8 @@ export const defaultBill = {
|
|||||||
reference_no: '',
|
reference_no: '',
|
||||||
note: '',
|
note: '',
|
||||||
open: '',
|
open: '',
|
||||||
|
branch_id: '',
|
||||||
|
warehouse_id: '',
|
||||||
entries: [...repeatValue(defaultBillEntry, MIN_LINES_NUMBER)],
|
entries: [...repeatValue(defaultBillEntry, MIN_LINES_NUMBER)],
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -177,3 +183,34 @@ export const handleErrors = (errors, { setErrors }) => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useSetPrimaryBranchToForm = () => {
|
||||||
|
const { setFieldValue } = useFormikContext();
|
||||||
|
const { branches, isBranchesSuccess } = useBillFormContext();
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (isBranchesSuccess) {
|
||||||
|
const primaryBranch = branches.find((b) => b.primary) || first(branches);
|
||||||
|
|
||||||
|
if (primaryBranch) {
|
||||||
|
setFieldValue('branch_id', primaryBranch.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [isBranchesSuccess, setFieldValue, branches]);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useSetPrimaryWarehouseToForm = () => {
|
||||||
|
const { setFieldValue } = useFormikContext();
|
||||||
|
const { warehouses, isWarehousesSuccess } = useBillFormContext();
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (isWarehousesSuccess) {
|
||||||
|
const primaryWarehouse =
|
||||||
|
warehouses.find((b) => b.primary) || first(warehouses);
|
||||||
|
|
||||||
|
if (primaryWarehouse) {
|
||||||
|
setFieldValue('warehouse_id', primaryWarehouse.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [isWarehousesSuccess, setFieldValue, warehouses]);
|
||||||
|
};
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import VendorCreditNoteItemsEntriesEditor from './VendorCreditNoteItemsEntriesEd
|
|||||||
import VendorCreditNoteFormFooter from './VendorCreditNoteFormFooter';
|
import VendorCreditNoteFormFooter from './VendorCreditNoteFormFooter';
|
||||||
import VendorCreditNoteFloatingActions from './VendorCreditNoteFloatingActions';
|
import VendorCreditNoteFloatingActions from './VendorCreditNoteFloatingActions';
|
||||||
import VendorCreditNoteFormDialogs from './VendorCreditNoteFormDialogs';
|
import VendorCreditNoteFormDialogs from './VendorCreditNoteFormDialogs';
|
||||||
|
import VendorCreditNoteFormTopBar from './VendorCreditNoteFormTopBar';
|
||||||
|
|
||||||
import { useVendorCreditNoteFormContext } from './VendorCreditNoteFormProvider';
|
import { useVendorCreditNoteFormContext } from './VendorCreditNoteFormProvider';
|
||||||
|
|
||||||
@@ -151,6 +152,7 @@ function VendorCreditNoteForm({
|
|||||||
onSubmit={handleFormSubmit}
|
onSubmit={handleFormSubmit}
|
||||||
>
|
>
|
||||||
<Form>
|
<Form>
|
||||||
|
<VendorCreditNoteFormTopBar />
|
||||||
<VendorCreditNoteFormHeader />
|
<VendorCreditNoteFormHeader />
|
||||||
<VendorCreditNoteItemsEntriesEditor />
|
<VendorCreditNoteItemsEntriesEditor />
|
||||||
<VendorCreditNoteFormFooter />
|
<VendorCreditNoteFormFooter />
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ const getSchema = Yup.object().shape({
|
|||||||
.max(DATATYPES_LENGTH.TEXT)
|
.max(DATATYPES_LENGTH.TEXT)
|
||||||
.label(intl.get('note')),
|
.label(intl.get('note')),
|
||||||
open: Yup.boolean(),
|
open: Yup.boolean(),
|
||||||
|
branch_id: Yup.string(),
|
||||||
|
warehouse_id: Yup.string(),
|
||||||
entries: Yup.array().of(
|
entries: Yup.array().of(
|
||||||
Yup.object().shape({
|
Yup.object().shape({
|
||||||
quantity: Yup.number()
|
quantity: Yup.number()
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import {
|
|||||||
useCreateVendorCredit,
|
useCreateVendorCredit,
|
||||||
useEditVendorCredit,
|
useEditVendorCredit,
|
||||||
useVendorCredit,
|
useVendorCredit,
|
||||||
|
useWarehouses,
|
||||||
|
useBranches,
|
||||||
useItems,
|
useItems,
|
||||||
useVendors,
|
useVendors,
|
||||||
useSettingsVendorCredits,
|
useSettingsVendorCredits,
|
||||||
@@ -51,6 +53,20 @@ function VendorCreditNoteFormProvider({ vendorCreditId, ...props }) {
|
|||||||
enabled: !!billId,
|
enabled: !!billId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Fetch warehouses list.
|
||||||
|
const {
|
||||||
|
data: warehouses,
|
||||||
|
isLoading: isWarehouesLoading,
|
||||||
|
isSuccess: isWarehousesSuccess,
|
||||||
|
} = useWarehouses();
|
||||||
|
|
||||||
|
// Fetches the branches list.
|
||||||
|
const {
|
||||||
|
data: branches,
|
||||||
|
isLoading: isBranchesLoading,
|
||||||
|
isSuccess: isBranchesSuccess,
|
||||||
|
} = useBranches();
|
||||||
|
|
||||||
// Form submit payload.
|
// Form submit payload.
|
||||||
const [submitPayload, setSubmitPayload] = React.useState();
|
const [submitPayload, setSubmitPayload] = React.useState();
|
||||||
|
|
||||||
@@ -61,6 +77,9 @@ function VendorCreditNoteFormProvider({ vendorCreditId, ...props }) {
|
|||||||
// Determines whether the form in new mode.
|
// Determines whether the form in new mode.
|
||||||
const isNewMode = !vendorCreditId;
|
const isNewMode = !vendorCreditId;
|
||||||
|
|
||||||
|
// Determines whether the warehouse and branches are loading.
|
||||||
|
const isFeatureLoading = isWarehouesLoading || isBranchesLoading;
|
||||||
|
|
||||||
const newVendorCredit = !isEmpty(bill)
|
const newVendorCredit = !isEmpty(bill)
|
||||||
? transformToEditForm({
|
? transformToEditForm({
|
||||||
...pick(bill, ['vendor_id', 'entries']),
|
...pick(bill, ['vendor_id', 'entries']),
|
||||||
@@ -72,11 +91,16 @@ function VendorCreditNoteFormProvider({ vendorCreditId, ...props }) {
|
|||||||
items,
|
items,
|
||||||
vendors,
|
vendors,
|
||||||
vendorCredit,
|
vendorCredit,
|
||||||
|
warehouses,
|
||||||
|
branches,
|
||||||
submitPayload,
|
submitPayload,
|
||||||
isNewMode,
|
isNewMode,
|
||||||
newVendorCredit,
|
newVendorCredit,
|
||||||
|
|
||||||
isVendorCreditLoading,
|
isVendorCreditLoading,
|
||||||
|
isFeatureLoading,
|
||||||
|
isBranchesSuccess,
|
||||||
|
isWarehousesSuccess,
|
||||||
|
|
||||||
createVendorCreditMutate,
|
createVendorCreditMutate,
|
||||||
editVendorCreditMutate,
|
editVendorCreditMutate,
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import intl from 'react-intl-universal';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import {
|
||||||
|
Alignment,
|
||||||
|
Navbar,
|
||||||
|
NavbarGroup,
|
||||||
|
NavbarDivider,
|
||||||
|
Button,
|
||||||
|
Classes,
|
||||||
|
} from '@blueprintjs/core';
|
||||||
|
import {
|
||||||
|
useSetPrimaryBranchToForm,
|
||||||
|
useSetPrimaryWarehouseToForm,
|
||||||
|
} from './utils';
|
||||||
|
import { useFeatureCan } from 'hooks/state';
|
||||||
|
import { Icon, BranchSelect, FeatureCan, WarehouseSelect } from 'components';
|
||||||
|
import { useVendorCreditNoteFormContext } from './VendorCreditNoteFormProvider';
|
||||||
|
import { Features } from 'common';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vendor Credit note form topbar .
|
||||||
|
* @returns {JSX.Element}
|
||||||
|
*/
|
||||||
|
export default function VendorCreditNoteFormTopBar() {
|
||||||
|
// Features guard.
|
||||||
|
const { featureCan } = useFeatureCan();
|
||||||
|
|
||||||
|
// Sets the primary warehouse to form.
|
||||||
|
useSetPrimaryWarehouseToForm();
|
||||||
|
|
||||||
|
// Sets the primary branch to form.
|
||||||
|
useSetPrimaryBranchToForm();
|
||||||
|
|
||||||
|
// Can't display the navigation bar if warehouses or branches feature is not enabled.
|
||||||
|
if (!featureCan(Features.Warehouses) || !featureCan(Features.Branches)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Navbar className={'navbar--dashboard-topbar'}>
|
||||||
|
<NavbarGroup align={Alignment.LEFT}>
|
||||||
|
<FeatureCan feature={Features.Branches}>
|
||||||
|
<VendorCreditNoteFormSelectBranch />
|
||||||
|
</FeatureCan>
|
||||||
|
{featureCan(Features.Warehouses) && featureCan(Features.Branches) && (
|
||||||
|
<NavbarDivider />
|
||||||
|
)}
|
||||||
|
<FeatureCan feature={Features.Warehouses}>
|
||||||
|
<VendorCreditFormSelectWarehouse />
|
||||||
|
</FeatureCan>
|
||||||
|
</NavbarGroup>
|
||||||
|
</Navbar>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function VendorCreditNoteFormSelectBranch() {
|
||||||
|
// Vendor credit note form context.
|
||||||
|
const { branches, isBranchesLoading } = useVendorCreditNoteFormContext();
|
||||||
|
|
||||||
|
return isBranchesLoading ? (
|
||||||
|
<DetailsBarSkeletonBase className={Classes.SKELETON} />
|
||||||
|
) : (
|
||||||
|
<BranchSelect
|
||||||
|
name={'branch_id'}
|
||||||
|
branches={branches}
|
||||||
|
input={VendorCreditNoteBranchSelectButton}
|
||||||
|
popoverProps={{ minimal: true }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function VendorCreditFormSelectWarehouse() {
|
||||||
|
// vendor credit note form context.
|
||||||
|
const { warehouses, isWarehouesLoading } = useVendorCreditNoteFormContext();
|
||||||
|
|
||||||
|
return isWarehouesLoading ? (
|
||||||
|
<DetailsBarSkeletonBase className={Classes.SKELETON} />
|
||||||
|
) : (
|
||||||
|
<WarehouseSelect
|
||||||
|
name={'warehouse_id'}
|
||||||
|
warehouses={warehouses}
|
||||||
|
input={VendorCreditNoteWarehouseSelectButton}
|
||||||
|
popoverProps={{ minimal: true }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function VendorCreditNoteWarehouseSelectButton({ label }) {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
text={intl.get('invoice.warehouse_button.label', { label })}
|
||||||
|
minimal={true}
|
||||||
|
small={true}
|
||||||
|
icon={<Icon icon={'warehouse-16'} iconSize={16} />}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function VendorCreditNoteBranchSelectButton({ label }) {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
text={intl.get('invoice.branch_button.label', { label })}
|
||||||
|
minimal={true}
|
||||||
|
small={true}
|
||||||
|
icon={<Icon icon={'branch-16'} iconSize={16} />}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const DetailsBarSkeletonBase = styled.div`
|
||||||
|
letter-spacing: 10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-left: 10px;
|
||||||
|
font-size: 8px;
|
||||||
|
width: 140px;
|
||||||
|
height: 10px;
|
||||||
|
`;
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
import { first } from 'lodash';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
defaultFastFieldShouldUpdate,
|
defaultFastFieldShouldUpdate,
|
||||||
@@ -14,6 +15,7 @@ import {
|
|||||||
ensureEntriesHaveEmptyLine,
|
ensureEntriesHaveEmptyLine,
|
||||||
} from 'containers/Entries/utils';
|
} from 'containers/Entries/utils';
|
||||||
import { useFormikContext } from 'formik';
|
import { useFormikContext } from 'formik';
|
||||||
|
import { useVendorCreditNoteFormContext } from './VendorCreditNoteFormProvider';
|
||||||
|
|
||||||
export const MIN_LINES_NUMBER = 4;
|
export const MIN_LINES_NUMBER = 4;
|
||||||
|
|
||||||
@@ -37,6 +39,8 @@ export const defaultVendorsCreditNote = {
|
|||||||
vendor_credit_date: moment(new Date()).format('YYYY-MM-DD'),
|
vendor_credit_date: moment(new Date()).format('YYYY-MM-DD'),
|
||||||
reference_no: '',
|
reference_no: '',
|
||||||
note: '',
|
note: '',
|
||||||
|
branch_id: '',
|
||||||
|
warehouse_id: '',
|
||||||
entries: [...repeatValue(defaultCreditNoteEntry, MIN_LINES_NUMBER)],
|
entries: [...repeatValue(defaultCreditNoteEntry, MIN_LINES_NUMBER)],
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -129,3 +133,34 @@ export const useObserveVendorCreditNoSettings = (prefix, nextNumber) => {
|
|||||||
setFieldValue('vendor_credit_number', creditNo);
|
setFieldValue('vendor_credit_number', creditNo);
|
||||||
}, [setFieldValue, prefix, nextNumber]);
|
}, [setFieldValue, prefix, nextNumber]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useSetPrimaryBranchToForm = () => {
|
||||||
|
const { setFieldValue } = useFormikContext();
|
||||||
|
const { branches, isBranchesSuccess } = useVendorCreditNoteFormContext();
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (isBranchesSuccess) {
|
||||||
|
const primaryBranch = branches.find((b) => b.primary) || first(branches);
|
||||||
|
|
||||||
|
if (primaryBranch) {
|
||||||
|
setFieldValue('branch_id', primaryBranch.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [isBranchesSuccess, setFieldValue, branches]);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useSetPrimaryWarehouseToForm = () => {
|
||||||
|
const { setFieldValue } = useFormikContext();
|
||||||
|
const { warehouses, isWarehousesSuccess } = useVendorCreditNoteFormContext();
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (isWarehousesSuccess) {
|
||||||
|
const primaryWarehouse =
|
||||||
|
warehouses.find((b) => b.primary) || first(warehouses);
|
||||||
|
|
||||||
|
if (primaryWarehouse) {
|
||||||
|
setFieldValue('warehouse_id', primaryWarehouse.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [isWarehousesSuccess, setFieldValue, warehouses]);
|
||||||
|
};
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import PaymentMadeHeader from './PaymentMadeFormHeader';
|
|||||||
import PaymentMadeFloatingActions from './PaymentMadeFloatingActions';
|
import PaymentMadeFloatingActions from './PaymentMadeFloatingActions';
|
||||||
import PaymentMadeFooter from './PaymentMadeFooter';
|
import PaymentMadeFooter from './PaymentMadeFooter';
|
||||||
import PaymentMadeFormBody from './PaymentMadeFormBody';
|
import PaymentMadeFormBody from './PaymentMadeFormBody';
|
||||||
|
import PaymentMadeFormTopBar from './PaymentMadeFormTopBar';
|
||||||
import { PaymentMadeInnerProvider } from './PaymentMadeInnerProvider';
|
import { PaymentMadeInnerProvider } from './PaymentMadeInnerProvider';
|
||||||
|
|
||||||
import withSettings from 'containers/Settings/withSettings';
|
import withSettings from 'containers/Settings/withSettings';
|
||||||
@@ -145,6 +146,7 @@ function PaymentMadeForm({
|
|||||||
>
|
>
|
||||||
<Form>
|
<Form>
|
||||||
<PaymentMadeInnerProvider>
|
<PaymentMadeInnerProvider>
|
||||||
|
<PaymentMadeFormTopBar />
|
||||||
<PaymentMadeHeader />
|
<PaymentMadeHeader />
|
||||||
<PaymentMadeFormBody />
|
<PaymentMadeFormBody />
|
||||||
<PaymentMadeFooter />
|
<PaymentMadeFooter />
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ const Schema = Yup.object().shape({
|
|||||||
.label(intl.get('payment_no_')),
|
.label(intl.get('payment_no_')),
|
||||||
reference: Yup.string().min(1).max(DATATYPES_LENGTH.STRING).nullable(),
|
reference: Yup.string().min(1).max(DATATYPES_LENGTH.STRING).nullable(),
|
||||||
description: Yup.string().max(DATATYPES_LENGTH.TEXT),
|
description: Yup.string().max(DATATYPES_LENGTH.TEXT),
|
||||||
|
branch_id: Yup.string(),
|
||||||
entries: Yup.array().of(
|
entries: Yup.array().of(
|
||||||
Yup.object().shape({
|
Yup.object().shape({
|
||||||
id: Yup.number().nullable(),
|
id: Yup.number().nullable(),
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
useAccounts,
|
useAccounts,
|
||||||
useVendors,
|
useVendors,
|
||||||
useItems,
|
useItems,
|
||||||
|
useBranches,
|
||||||
usePaymentMadeEditPage,
|
usePaymentMadeEditPage,
|
||||||
useSettings,
|
useSettings,
|
||||||
useCreatePaymentMade,
|
useCreatePaymentMade,
|
||||||
@@ -45,6 +46,13 @@ function PaymentMadeFormProvider({ paymentMadeId, ...props }) {
|
|||||||
enabled: !!paymentMadeId,
|
enabled: !!paymentMadeId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Fetches the branches list.
|
||||||
|
const {
|
||||||
|
data: branches,
|
||||||
|
isLoading: isBranchesLoading,
|
||||||
|
isSuccess: isBranchesSuccess,
|
||||||
|
} = useBranches();
|
||||||
|
|
||||||
// Fetch payment made settings.
|
// Fetch payment made settings.
|
||||||
useSettings();
|
useSettings();
|
||||||
|
|
||||||
@@ -54,6 +62,8 @@ function PaymentMadeFormProvider({ paymentMadeId, ...props }) {
|
|||||||
|
|
||||||
const isNewMode = !paymentMadeId;
|
const isNewMode = !paymentMadeId;
|
||||||
|
|
||||||
|
const isFeatureLoading = isBranchesLoading;
|
||||||
|
|
||||||
// Provider payload.
|
// Provider payload.
|
||||||
const provider = {
|
const provider = {
|
||||||
paymentMadeId,
|
paymentMadeId,
|
||||||
@@ -62,6 +72,7 @@ function PaymentMadeFormProvider({ paymentMadeId, ...props }) {
|
|||||||
paymentMadeEditPage,
|
paymentMadeEditPage,
|
||||||
vendors,
|
vendors,
|
||||||
items,
|
items,
|
||||||
|
branches,
|
||||||
submitPayload,
|
submitPayload,
|
||||||
paymentVendorId,
|
paymentVendorId,
|
||||||
|
|
||||||
@@ -72,6 +83,8 @@ function PaymentMadeFormProvider({ paymentMadeId, ...props }) {
|
|||||||
isVendorsLoading,
|
isVendorsLoading,
|
||||||
isPaymentFetching,
|
isPaymentFetching,
|
||||||
isPaymentLoading,
|
isPaymentLoading,
|
||||||
|
isFeatureLoading,
|
||||||
|
isBranchesSuccess,
|
||||||
|
|
||||||
createPaymentMadeMutate,
|
createPaymentMadeMutate,
|
||||||
editPaymentMadeMutate,
|
editPaymentMadeMutate,
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import intl from 'react-intl-universal';
|
||||||
|
import {
|
||||||
|
Alignment,
|
||||||
|
Navbar,
|
||||||
|
NavbarGroup,
|
||||||
|
Button,
|
||||||
|
Classes,
|
||||||
|
} from '@blueprintjs/core';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import { useSetPrimaryBranchToForm } from './utils';
|
||||||
|
import { useFeatureCan } from 'hooks/state';
|
||||||
|
import { Icon, BranchSelect, FeatureCan } from 'components';
|
||||||
|
import { usePaymentMadeFormContext } from './PaymentMadeFormProvider';
|
||||||
|
import { Features } from 'common';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Payment made from top bar.
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export default function PaymentMadeFormTopBar() {
|
||||||
|
// Features guard.
|
||||||
|
const { featureCan } = useFeatureCan();
|
||||||
|
|
||||||
|
// Sets the primary branch to form.
|
||||||
|
useSetPrimaryBranchToForm();
|
||||||
|
|
||||||
|
// Can't display the navigation bar if branches feature is not enabled.
|
||||||
|
if (!featureCan(Features.Branches)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Navbar className={'navbar--dashboard-topbar'}>
|
||||||
|
<NavbarGroup align={Alignment.LEFT}>
|
||||||
|
<FeatureCan feature={Features.Branches}>
|
||||||
|
<PaymentMadeFormSelectBranch />
|
||||||
|
</FeatureCan>
|
||||||
|
</NavbarGroup>
|
||||||
|
</Navbar>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function PaymentMadeFormSelectBranch() {
|
||||||
|
// payment made form context.
|
||||||
|
const { branches, isBranchesLoading } = usePaymentMadeFormContext();
|
||||||
|
|
||||||
|
return isBranchesLoading ? (
|
||||||
|
<DetailsBarSkeletonBase className={Classes.SKELETON} />
|
||||||
|
) : (
|
||||||
|
<BranchSelect
|
||||||
|
name={'branch_id'}
|
||||||
|
branches={branches}
|
||||||
|
input={PaymentMadeBranchSelectButton}
|
||||||
|
popoverProps={{ minimal: true }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function PaymentMadeBranchSelectButton({ label }) {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
text={intl.get('invoice.branch_button.label', { label })}
|
||||||
|
minimal={true}
|
||||||
|
small={true}
|
||||||
|
icon={<Icon icon={'branch-16'} iconSize={16} />}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const DetailsBarSkeletonBase = styled.div`
|
||||||
|
letter-spacing: 10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-left: 10px;
|
||||||
|
font-size: 8px;
|
||||||
|
width: 140px;
|
||||||
|
height: 10px;
|
||||||
|
`;
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
|
import React from 'react';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { pick } from 'lodash';
|
import { pick, first } from 'lodash';
|
||||||
|
import { useFormikContext } from 'formik';
|
||||||
|
import { usePaymentMadeFormContext } from './PaymentMadeFormProvider';
|
||||||
import {
|
import {
|
||||||
defaultFastFieldShouldUpdate,
|
defaultFastFieldShouldUpdate,
|
||||||
safeSumBy,
|
safeSumBy,
|
||||||
@@ -31,6 +34,7 @@ export const defaultPaymentMade = {
|
|||||||
payment_number: '',
|
payment_number: '',
|
||||||
statement: '',
|
statement: '',
|
||||||
currency_code: '',
|
currency_code: '',
|
||||||
|
branch_id: '',
|
||||||
entries: [],
|
entries: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -91,3 +95,18 @@ export const transformFormToRequest = (form) => {
|
|||||||
|
|
||||||
return { ...form, entries: orderingLinesIndexes(entries) };
|
return { ...form, entries: orderingLinesIndexes(entries) };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useSetPrimaryBranchToForm = () => {
|
||||||
|
const { setFieldValue } = useFormikContext();
|
||||||
|
const { branches, isBranchesSuccess } = usePaymentMadeFormContext();
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (isBranchesSuccess) {
|
||||||
|
const primaryBranch = branches.find((b) => b.primary) || first(branches);
|
||||||
|
|
||||||
|
if (primaryBranch) {
|
||||||
|
setFieldValue('branch_id', primaryBranch.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [isBranchesSuccess, setFieldValue, branches]);
|
||||||
|
};
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import CreditNoteItemsEntriesEditorField from './CreditNoteItemsEntriesEditorFie
|
|||||||
import CreditNoteFormFooter from './CreditNoteFormFooter';
|
import CreditNoteFormFooter from './CreditNoteFormFooter';
|
||||||
import CreditNoteFloatingActions from './CreditNoteFloatingActions';
|
import CreditNoteFloatingActions from './CreditNoteFloatingActions';
|
||||||
import CreditNoteFormDialogs from './CreditNoteFormDialogs';
|
import CreditNoteFormDialogs from './CreditNoteFormDialogs';
|
||||||
|
import CreditNoteFormTopBar from './CreditNoteFormTopBar';
|
||||||
|
|
||||||
import { AppToaster } from 'components';
|
import { AppToaster } from 'components';
|
||||||
|
|
||||||
@@ -153,6 +154,7 @@ function CreditNoteForm({
|
|||||||
onSubmit={handleFormSubmit}
|
onSubmit={handleFormSubmit}
|
||||||
>
|
>
|
||||||
<Form>
|
<Form>
|
||||||
|
<CreditNoteFormTopBar />
|
||||||
<CreditNoteFormHeader />
|
<CreditNoteFormHeader />
|
||||||
<CreditNoteItemsEntriesEditorField />
|
<CreditNoteItemsEntriesEditorField />
|
||||||
<CreditNoteFormFooter />
|
<CreditNoteFormFooter />
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ const getSchema = () =>
|
|||||||
.min(1)
|
.min(1)
|
||||||
.max(DATATYPES_LENGTH.TEXT)
|
.max(DATATYPES_LENGTH.TEXT)
|
||||||
.label(intl.get('note')),
|
.label(intl.get('note')),
|
||||||
|
branch_id: Yup.string(),
|
||||||
|
warehouse_id: Yup.string(),
|
||||||
entries: Yup.array().of(
|
entries: Yup.array().of(
|
||||||
Yup.object().shape({
|
Yup.object().shape({
|
||||||
quantity: Yup.number()
|
quantity: Yup.number()
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import {
|
|||||||
useEditCreditNote,
|
useEditCreditNote,
|
||||||
useItems,
|
useItems,
|
||||||
useCustomers,
|
useCustomers,
|
||||||
|
useWarehouses,
|
||||||
|
useBranches,
|
||||||
useSettingsCreditNotes,
|
useSettingsCreditNotes,
|
||||||
useInvoice,
|
useInvoice,
|
||||||
} from 'hooks/query';
|
} from 'hooks/query';
|
||||||
@@ -49,6 +51,20 @@ function CreditNoteFormProvider({ creditNoteId, ...props }) {
|
|||||||
enabled: !!invoiceId,
|
enabled: !!invoiceId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Fetch warehouses list.
|
||||||
|
const {
|
||||||
|
data: warehouses,
|
||||||
|
isLoading: isWarehouesLoading,
|
||||||
|
isSuccess: isWarehousesSuccess,
|
||||||
|
} = useWarehouses();
|
||||||
|
|
||||||
|
// Fetches the branches list.
|
||||||
|
const {
|
||||||
|
data: branches,
|
||||||
|
isLoading: isBranchesLoading,
|
||||||
|
isSuccess: isBranchesSuccess,
|
||||||
|
} = useBranches();
|
||||||
|
|
||||||
// Handle fetching settings.
|
// Handle fetching settings.
|
||||||
useSettingsCreditNotes();
|
useSettingsCreditNotes();
|
||||||
|
|
||||||
@@ -62,6 +78,9 @@ function CreditNoteFormProvider({ creditNoteId, ...props }) {
|
|||||||
// Determines whether the form in new mode.
|
// Determines whether the form in new mode.
|
||||||
const isNewMode = !creditNoteId;
|
const isNewMode = !creditNoteId;
|
||||||
|
|
||||||
|
// Determines whether the warehouse and branches are loading.
|
||||||
|
const isFeatureLoading = isWarehouesLoading || isBranchesLoading;
|
||||||
|
|
||||||
const newCreditNote = !isEmpty(invoice)
|
const newCreditNote = !isEmpty(invoice)
|
||||||
? transformToEditForm({
|
? transformToEditForm({
|
||||||
...pick(invoice, ['customer_id', 'entries']),
|
...pick(invoice, ['customer_id', 'entries']),
|
||||||
@@ -73,12 +92,17 @@ function CreditNoteFormProvider({ creditNoteId, ...props }) {
|
|||||||
items,
|
items,
|
||||||
customers,
|
customers,
|
||||||
creditNote,
|
creditNote,
|
||||||
|
branches,
|
||||||
|
warehouses,
|
||||||
submitPayload,
|
submitPayload,
|
||||||
isNewMode,
|
isNewMode,
|
||||||
newCreditNote,
|
newCreditNote,
|
||||||
|
|
||||||
isItemsLoading,
|
isItemsLoading,
|
||||||
isCustomersLoading,
|
isCustomersLoading,
|
||||||
|
isFeatureLoading,
|
||||||
|
isBranchesSuccess,
|
||||||
|
isWarehousesSuccess,
|
||||||
|
|
||||||
createCreditNoteMutate,
|
createCreditNoteMutate,
|
||||||
editCreditNoteMutate,
|
editCreditNoteMutate,
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import intl from 'react-intl-universal';
|
||||||
|
import {
|
||||||
|
Alignment,
|
||||||
|
Navbar,
|
||||||
|
NavbarGroup,
|
||||||
|
NavbarDivider,
|
||||||
|
Button,
|
||||||
|
Classes,
|
||||||
|
} from '@blueprintjs/core';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import {
|
||||||
|
useSetPrimaryBranchToForm,
|
||||||
|
useSetPrimaryWarehouseToForm,
|
||||||
|
} from './utils';
|
||||||
|
import { useFeatureCan } from 'hooks/state';
|
||||||
|
import { Icon, BranchSelect, FeatureCan, WarehouseSelect } from 'components';
|
||||||
|
import { useCreditNoteFormContext } from './CreditNoteFormProvider';
|
||||||
|
import { Features } from 'common';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Credit note form topbar .
|
||||||
|
* @returns {JSX.Element}
|
||||||
|
*/
|
||||||
|
export default function CreditNoteFormTopbar() {
|
||||||
|
// Features guard.
|
||||||
|
const { featureCan } = useFeatureCan();
|
||||||
|
|
||||||
|
// Sets the primary warehouse to form.
|
||||||
|
useSetPrimaryWarehouseToForm();
|
||||||
|
|
||||||
|
// Sets the primary branch to form.
|
||||||
|
useSetPrimaryBranchToForm();
|
||||||
|
|
||||||
|
// Can't display the navigation bar if warehouses or branches feature is not enabled.
|
||||||
|
if (!featureCan(Features.Warehouses) || !featureCan(Features.Branches)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Navbar className={'navbar--dashboard-topbar'}>
|
||||||
|
<NavbarGroup align={Alignment.LEFT}>
|
||||||
|
<FeatureCan feature={Features.Branches}>
|
||||||
|
<CreditNoteFormSelectBranch />
|
||||||
|
</FeatureCan>
|
||||||
|
{featureCan(Features.Warehouses) && featureCan(Features.Branches) && (
|
||||||
|
<NavbarDivider />
|
||||||
|
)}
|
||||||
|
<FeatureCan feature={Features.Warehouses}>
|
||||||
|
<CreditFormSelectWarehouse />
|
||||||
|
</FeatureCan>
|
||||||
|
</NavbarGroup>
|
||||||
|
</Navbar>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function CreditNoteFormSelectBranch() {
|
||||||
|
// Credit note form context.
|
||||||
|
const { branches, isBranchesLoading } = useCreditNoteFormContext();
|
||||||
|
|
||||||
|
return isBranchesLoading ? (
|
||||||
|
<DetailsBarSkeletonBase className={Classes.SKELETON} />
|
||||||
|
) : (
|
||||||
|
<BranchSelect
|
||||||
|
name={'branch_id'}
|
||||||
|
branches={branches}
|
||||||
|
input={CreditNoteBranchSelectButton}
|
||||||
|
popoverProps={{ minimal: true }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function CreditFormSelectWarehouse() {
|
||||||
|
// Credit note form context.
|
||||||
|
const { warehouses, isWarehouesLoading } = useCreditNoteFormContext();
|
||||||
|
|
||||||
|
return isWarehouesLoading ? (
|
||||||
|
<DetailsBarSkeletonBase className={Classes.SKELETON} />
|
||||||
|
) : (
|
||||||
|
<WarehouseSelect
|
||||||
|
name={'warehouse_id'}
|
||||||
|
warehouses={warehouses}
|
||||||
|
input={CreditNoteWarehouseSelectButton}
|
||||||
|
popoverProps={{ minimal: true }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function CreditNoteWarehouseSelectButton({ label }) {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
text={intl.get('invoice.warehouse_button.label', { label })}
|
||||||
|
minimal={true}
|
||||||
|
small={true}
|
||||||
|
icon={<Icon icon={'warehouse-16'} iconSize={16} />}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function CreditNoteBranchSelectButton({ label }) {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
text={intl.get('invoice.branch_button.label', { label })}
|
||||||
|
minimal={true}
|
||||||
|
small={true}
|
||||||
|
icon={<Icon icon={'branch-16'} iconSize={16} />}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const DetailsBarSkeletonBase = styled.div`
|
||||||
|
letter-spacing: 10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-left: 10px;
|
||||||
|
font-size: 8px;
|
||||||
|
width: 140px;
|
||||||
|
height: 10px;
|
||||||
|
`;
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
import { first } from 'lodash';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
defaultFastFieldShouldUpdate,
|
defaultFastFieldShouldUpdate,
|
||||||
@@ -10,6 +11,7 @@ import {
|
|||||||
orderingLinesIndexes,
|
orderingLinesIndexes,
|
||||||
} from 'utils';
|
} from 'utils';
|
||||||
import { useFormikContext } from 'formik';
|
import { useFormikContext } from 'formik';
|
||||||
|
import { useCreditNoteFormContext } from './CreditNoteFormProvider';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
updateItemsEntriesTotal,
|
updateItemsEntriesTotal,
|
||||||
@@ -39,6 +41,8 @@ export const defaultCreditNote = {
|
|||||||
reference_no: '',
|
reference_no: '',
|
||||||
note: '',
|
note: '',
|
||||||
terms_conditions: '',
|
terms_conditions: '',
|
||||||
|
branch_id: '',
|
||||||
|
warehouse_id: '',
|
||||||
entries: [...repeatValue(defaultCreditNoteEntry, MIN_LINES_NUMBER)],
|
entries: [...repeatValue(defaultCreditNoteEntry, MIN_LINES_NUMBER)],
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -131,3 +135,34 @@ export const useObserveCreditNoSettings = (prefix, nextNumber) => {
|
|||||||
setFieldValue('credit_note_number', creditNo);
|
setFieldValue('credit_note_number', creditNo);
|
||||||
}, [setFieldValue, prefix, nextNumber]);
|
}, [setFieldValue, prefix, nextNumber]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useSetPrimaryBranchToForm = () => {
|
||||||
|
const { setFieldValue } = useFormikContext();
|
||||||
|
const { branches, isBranchesSuccess } = useCreditNoteFormContext();
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (isBranchesSuccess) {
|
||||||
|
const primaryBranch = branches.find((b) => b.primary) || first(branches);
|
||||||
|
|
||||||
|
if (primaryBranch) {
|
||||||
|
setFieldValue('branch_id', primaryBranch.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [isBranchesSuccess, setFieldValue, branches]);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useSetPrimaryWarehouseToForm = () => {
|
||||||
|
const { setFieldValue } = useFormikContext();
|
||||||
|
const { warehouses, isWarehousesSuccess } = useCreditNoteFormContext();
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (isWarehousesSuccess) {
|
||||||
|
const primaryWarehouse =
|
||||||
|
warehouses.find((b) => b.primary) || first(warehouses);
|
||||||
|
|
||||||
|
if (primaryWarehouse) {
|
||||||
|
setFieldValue('warehouse_id', primaryWarehouse.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [isWarehousesSuccess, setFieldValue, warehouses]);
|
||||||
|
};
|
||||||
@@ -17,6 +17,7 @@ import EstimateItemsEntriesField from './EstimateItemsEntriesField';
|
|||||||
import EstimateFloatingActions from './EstimateFloatingActions';
|
import EstimateFloatingActions from './EstimateFloatingActions';
|
||||||
import EstimateFormFooter from './EstimateFormFooter';
|
import EstimateFormFooter from './EstimateFormFooter';
|
||||||
import EstimateFormDialogs from './EstimateFormDialogs';
|
import EstimateFormDialogs from './EstimateFormDialogs';
|
||||||
|
import EstimtaeFormTopBar from './EstimtaeFormTopBar';
|
||||||
|
|
||||||
import withSettings from 'containers/Settings/withSettings';
|
import withSettings from 'containers/Settings/withSettings';
|
||||||
import withCurrentOrganization from 'containers/Organization/withCurrentOrganization';
|
import withCurrentOrganization from 'containers/Organization/withCurrentOrganization';
|
||||||
@@ -28,7 +29,7 @@ import {
|
|||||||
transformToEditForm,
|
transformToEditForm,
|
||||||
defaultEstimate,
|
defaultEstimate,
|
||||||
transfromsFormValuesToRequest,
|
transfromsFormValuesToRequest,
|
||||||
handleErrors
|
handleErrors,
|
||||||
} from './utils';
|
} from './utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -153,6 +154,7 @@ function EstimateForm({
|
|||||||
onSubmit={handleFormSubmit}
|
onSubmit={handleFormSubmit}
|
||||||
>
|
>
|
||||||
<Form>
|
<Form>
|
||||||
|
<EstimtaeFormTopBar />
|
||||||
<EstimateFormHeader />
|
<EstimateFormHeader />
|
||||||
<EstimateItemsEntriesField />
|
<EstimateItemsEntriesField />
|
||||||
<EstimateFormFooter />
|
<EstimateFormFooter />
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ const Schema = Yup.object().shape({
|
|||||||
.max(DATATYPES_LENGTH.TEXT)
|
.max(DATATYPES_LENGTH.TEXT)
|
||||||
.label(intl.get('note')),
|
.label(intl.get('note')),
|
||||||
delivered: Yup.boolean(),
|
delivered: Yup.boolean(),
|
||||||
|
branch_id: Yup.string(),
|
||||||
|
warehouse_id: Yup.string(),
|
||||||
entries: Yup.array().of(
|
entries: Yup.array().of(
|
||||||
Yup.object().shape({
|
Yup.object().shape({
|
||||||
quantity: Yup.number()
|
quantity: Yup.number()
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import DashboardInsider from 'components/Dashboard/DashboardInsider';
|
|||||||
import {
|
import {
|
||||||
useEstimate,
|
useEstimate,
|
||||||
useCustomers,
|
useCustomers,
|
||||||
|
useWarehouses,
|
||||||
|
useBranches,
|
||||||
useItems,
|
useItems,
|
||||||
useSettingsEstimates,
|
useSettingsEstimates,
|
||||||
useCreateEstimate,
|
useCreateEstimate,
|
||||||
@@ -39,6 +41,20 @@ function EstimateFormProvider({ estimateId, ...props }) {
|
|||||||
isLoading: isCustomersLoading,
|
isLoading: isCustomersLoading,
|
||||||
} = useCustomers({ page_size: 10000 });
|
} = useCustomers({ page_size: 10000 });
|
||||||
|
|
||||||
|
// Fetch warehouses list.
|
||||||
|
const {
|
||||||
|
data: warehouses,
|
||||||
|
isLoading: isWarehouesLoading,
|
||||||
|
isSuccess: isWarehousesSuccess,
|
||||||
|
} = useWarehouses();
|
||||||
|
|
||||||
|
// Fetches the branches list.
|
||||||
|
const {
|
||||||
|
data: branches,
|
||||||
|
isLoading: isBranchesLoading,
|
||||||
|
isSuccess: isBranchesSuccess,
|
||||||
|
} = useBranches();
|
||||||
|
|
||||||
// Handle fetch settings.
|
// Handle fetch settings.
|
||||||
useSettingsEstimates();
|
useSettingsEstimates();
|
||||||
|
|
||||||
@@ -51,12 +67,17 @@ function EstimateFormProvider({ estimateId, ...props }) {
|
|||||||
|
|
||||||
const isNewMode = !estimateId;
|
const isNewMode = !estimateId;
|
||||||
|
|
||||||
|
// Determines whether the warehouse and branches are loading.
|
||||||
|
const isFeatureLoading = isWarehouesLoading || isBranchesLoading;
|
||||||
|
|
||||||
// Provider payload.
|
// Provider payload.
|
||||||
const provider = {
|
const provider = {
|
||||||
estimateId,
|
estimateId,
|
||||||
estimate,
|
estimate,
|
||||||
items,
|
items,
|
||||||
customers,
|
customers,
|
||||||
|
branches,
|
||||||
|
warehouses,
|
||||||
isNewMode,
|
isNewMode,
|
||||||
|
|
||||||
isItemsFetching,
|
isItemsFetching,
|
||||||
@@ -65,7 +86,9 @@ function EstimateFormProvider({ estimateId, ...props }) {
|
|||||||
isCustomersLoading,
|
isCustomersLoading,
|
||||||
isItemsLoading,
|
isItemsLoading,
|
||||||
isEstimateLoading,
|
isEstimateLoading,
|
||||||
|
isFeatureLoading,
|
||||||
|
isBranchesSuccess,
|
||||||
|
isWarehousesSuccess,
|
||||||
submitPayload,
|
submitPayload,
|
||||||
setSubmitPayload,
|
setSubmitPayload,
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import intl from 'react-intl-universal';
|
||||||
|
import {
|
||||||
|
Alignment,
|
||||||
|
Navbar,
|
||||||
|
NavbarGroup,
|
||||||
|
NavbarDivider,
|
||||||
|
Button,
|
||||||
|
Classes,
|
||||||
|
} from '@blueprintjs/core';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import {
|
||||||
|
useSetPrimaryBranchToForm,
|
||||||
|
useSetPrimaryWarehouseToForm,
|
||||||
|
} from './utils';
|
||||||
|
import { useFeatureCan } from 'hooks/state';
|
||||||
|
import { Icon, BranchSelect, FeatureCan, WarehouseSelect } from 'components';
|
||||||
|
import { useEstimateFormContext } from './EstimateFormProvider';
|
||||||
|
import { Features } from 'common';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Estimate form topbar .
|
||||||
|
* @returns {JSX.Element}
|
||||||
|
*/
|
||||||
|
export default function EstimtaeFormTopBar() {
|
||||||
|
// Features guard.
|
||||||
|
const { featureCan } = useFeatureCan();
|
||||||
|
|
||||||
|
// Sets the primary warehouse to form.
|
||||||
|
useSetPrimaryWarehouseToForm();
|
||||||
|
|
||||||
|
// Sets the primary branch to form.
|
||||||
|
useSetPrimaryBranchToForm();
|
||||||
|
|
||||||
|
// Can't display the navigation bar if warehouses or branches feature is not enabled.
|
||||||
|
if (!featureCan(Features.Warehouses) || !featureCan(Features.Branches)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Navbar className={'navbar--dashboard-topbar'}>
|
||||||
|
<NavbarGroup align={Alignment.LEFT}>
|
||||||
|
<FeatureCan feature={Features.Branches}>
|
||||||
|
<EstimateFormSelectBranch />
|
||||||
|
</FeatureCan>
|
||||||
|
{featureCan(Features.Warehouses) && featureCan(Features.Branches) && (
|
||||||
|
<NavbarDivider />
|
||||||
|
)}
|
||||||
|
<FeatureCan feature={Features.Warehouses}>
|
||||||
|
<EstimateFormSelectWarehouse />
|
||||||
|
</FeatureCan>
|
||||||
|
</NavbarGroup>
|
||||||
|
</Navbar>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function EstimateFormSelectBranch() {
|
||||||
|
// Estimate form context.
|
||||||
|
const { branches, isBranchesLoading } = useEstimateFormContext();
|
||||||
|
|
||||||
|
return isBranchesLoading ? (
|
||||||
|
<DetailsBarSkeletonBase className={Classes.SKELETON} />
|
||||||
|
) : (
|
||||||
|
<BranchSelect
|
||||||
|
name={'branch_id'}
|
||||||
|
branches={branches}
|
||||||
|
input={EstimateBranchSelectButton}
|
||||||
|
popoverProps={{ minimal: true }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function EstimateFormSelectWarehouse() {
|
||||||
|
// Estimate form context.
|
||||||
|
const { warehouses, isWarehouesLoading } = useEstimateFormContext();
|
||||||
|
|
||||||
|
return isWarehouesLoading ? (
|
||||||
|
<DetailsBarSkeletonBase className={Classes.SKELETON} />
|
||||||
|
) : (
|
||||||
|
<WarehouseSelect
|
||||||
|
name={'warehouse_id'}
|
||||||
|
warehouses={warehouses}
|
||||||
|
input={EstimateWarehouseSelectButton}
|
||||||
|
popoverProps={{ minimal: true }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function EstimateWarehouseSelectButton({ label }) {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
text={intl.get('invoice.warehouse_button.label', { label })}
|
||||||
|
minimal={true}
|
||||||
|
small={true}
|
||||||
|
icon={<Icon icon={'warehouse-16'} iconSize={16} />}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function EstimateBranchSelectButton({ label }) {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
text={intl.get('invoice.branch_button.label', { label })}
|
||||||
|
minimal={true}
|
||||||
|
small={true}
|
||||||
|
icon={<Icon icon={'branch-16'} iconSize={16} />}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const DetailsBarSkeletonBase = styled.div`
|
||||||
|
letter-spacing: 10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-left: 10px;
|
||||||
|
font-size: 8px;
|
||||||
|
width: 140px;
|
||||||
|
height: 10px;
|
||||||
|
`;
|
||||||
@@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
import { useFormikContext } from 'formik';
|
import { useFormikContext } from 'formik';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
import { omit } from 'lodash';
|
import { omit, first } from 'lodash';
|
||||||
import intl from 'react-intl-universal';
|
import intl from 'react-intl-universal';
|
||||||
import {
|
import {
|
||||||
defaultFastFieldShouldUpdate,
|
defaultFastFieldShouldUpdate,
|
||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
repeatValue,
|
repeatValue,
|
||||||
transformToForm,
|
transformToForm,
|
||||||
} from 'utils';
|
} from 'utils';
|
||||||
|
import { useEstimateFormContext } from './EstimateFormProvider';
|
||||||
import {
|
import {
|
||||||
updateItemsEntriesTotal,
|
updateItemsEntriesTotal,
|
||||||
ensureEntriesHaveEmptyLine,
|
ensureEntriesHaveEmptyLine,
|
||||||
@@ -36,6 +37,8 @@ export const defaultEstimate = {
|
|||||||
reference: '',
|
reference: '',
|
||||||
note: '',
|
note: '',
|
||||||
terms_conditions: '',
|
terms_conditions: '',
|
||||||
|
branch_id: '',
|
||||||
|
warehouse_id: '',
|
||||||
entries: [...repeatValue(defaultEstimateEntry, MIN_LINES_NUMBER)],
|
entries: [...repeatValue(defaultEstimateEntry, MIN_LINES_NUMBER)],
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -151,3 +154,34 @@ export const transfromsFormValuesToRequest = (values) => {
|
|||||||
entries: entries.map((entry) => ({ ...omit(entry, ['amount']) })),
|
entries: entries.map((entry) => ({ ...omit(entry, ['amount']) })),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useSetPrimaryWarehouseToForm = () => {
|
||||||
|
const { setFieldValue } = useFormikContext();
|
||||||
|
const { warehouses, isWarehousesSuccess } = useEstimateFormContext();
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (isWarehousesSuccess) {
|
||||||
|
const primaryWarehouse =
|
||||||
|
warehouses.find((b) => b.primary) || first(warehouses);
|
||||||
|
|
||||||
|
if (primaryWarehouse) {
|
||||||
|
setFieldValue('warehouse_id', primaryWarehouse.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [isWarehousesSuccess, setFieldValue, warehouses]);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useSetPrimaryBranchToForm = () => {
|
||||||
|
const { setFieldValue } = useFormikContext();
|
||||||
|
const { branches, isBranchesSuccess } = useEstimateFormContext();
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (isBranchesSuccess) {
|
||||||
|
const primaryBranch = branches.find((b) => b.primary) || first(branches);
|
||||||
|
|
||||||
|
if (primaryBranch) {
|
||||||
|
setFieldValue('branch_id', primaryBranch.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [isBranchesSuccess, setFieldValue, branches]);
|
||||||
|
};
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import PaymentReceiveFloatingActions from './PaymentReceiveFloatingActions';
|
|||||||
import PaymentReceiveFormFooter from './PaymentReceiveFormFooter';
|
import PaymentReceiveFormFooter from './PaymentReceiveFormFooter';
|
||||||
import PaymentReceiveFormAlerts from './PaymentReceiveFormAlerts';
|
import PaymentReceiveFormAlerts from './PaymentReceiveFormAlerts';
|
||||||
import PaymentReceiveFormDialogs from './PaymentReceiveFormDialogs';
|
import PaymentReceiveFormDialogs from './PaymentReceiveFormDialogs';
|
||||||
|
import PaymentReceiveFormTopBar from './PaymentReceiveFormTopBar';
|
||||||
import { PaymentReceiveInnerProvider } from './PaymentReceiveInnerProvider';
|
import { PaymentReceiveInnerProvider } from './PaymentReceiveInnerProvider';
|
||||||
|
|
||||||
import withSettings from 'containers/Settings/withSettings';
|
import withSettings from 'containers/Settings/withSettings';
|
||||||
@@ -178,6 +179,7 @@ function PaymentReceiveForm({
|
|||||||
>
|
>
|
||||||
<Form>
|
<Form>
|
||||||
<PaymentReceiveInnerProvider>
|
<PaymentReceiveInnerProvider>
|
||||||
|
<PaymentReceiveFormTopBar />
|
||||||
<PaymentReceiveHeader />
|
<PaymentReceiveHeader />
|
||||||
<PaymentReceiveFormBody />
|
<PaymentReceiveFormBody />
|
||||||
<PaymentReceiveFormFooter />
|
<PaymentReceiveFormFooter />
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ const Schema = Yup.object().shape({
|
|||||||
.label(intl.get('payment_receive_no_')),
|
.label(intl.get('payment_receive_no_')),
|
||||||
reference_no: Yup.string().min(1).max(DATATYPES_LENGTH.STRING).nullable(),
|
reference_no: Yup.string().min(1).max(DATATYPES_LENGTH.STRING).nullable(),
|
||||||
// statement: Yup.string().nullable().max(DATATYPES_LENGTH.TEXT),
|
// statement: Yup.string().nullable().max(DATATYPES_LENGTH.TEXT),
|
||||||
|
branch_id: Yup.string(),
|
||||||
entries: Yup.array().of(
|
entries: Yup.array().of(
|
||||||
Yup.object().shape({
|
Yup.object().shape({
|
||||||
id: Yup.number().nullable(),
|
id: Yup.number().nullable(),
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
usePaymentReceiveEditPage,
|
usePaymentReceiveEditPage,
|
||||||
useAccounts,
|
useAccounts,
|
||||||
useCustomers,
|
useCustomers,
|
||||||
|
useBranches,
|
||||||
useCreatePaymentReceive,
|
useCreatePaymentReceive,
|
||||||
useEditPaymentReceive,
|
useEditPaymentReceive,
|
||||||
} from 'hooks/query';
|
} from 'hooks/query';
|
||||||
@@ -42,9 +43,18 @@ function PaymentReceiveFormProvider({ paymentReceiveId, ...props }) {
|
|||||||
isLoading: isCustomersLoading,
|
isLoading: isCustomersLoading,
|
||||||
} = useCustomers({ page_size: 10000 });
|
} = useCustomers({ page_size: 10000 });
|
||||||
|
|
||||||
|
// Fetches the branches list.
|
||||||
|
const {
|
||||||
|
data: branches,
|
||||||
|
isLoading: isBranchesLoading,
|
||||||
|
isSuccess: isBranchesSuccess,
|
||||||
|
} = useBranches();
|
||||||
|
|
||||||
// Detarmines whether the new mode.
|
// Detarmines whether the new mode.
|
||||||
const isNewMode = !paymentReceiveId;
|
const isNewMode = !paymentReceiveId;
|
||||||
|
|
||||||
|
const isFeatureLoading = isBranchesLoading;
|
||||||
|
|
||||||
// Create and edit payment receive mutations.
|
// Create and edit payment receive mutations.
|
||||||
const { mutateAsync: editPaymentReceiveMutate } = useEditPaymentReceive();
|
const { mutateAsync: editPaymentReceiveMutate } = useEditPaymentReceive();
|
||||||
const { mutateAsync: createPaymentReceiveMutate } = useCreatePaymentReceive();
|
const { mutateAsync: createPaymentReceiveMutate } = useCreatePaymentReceive();
|
||||||
@@ -56,11 +66,14 @@ function PaymentReceiveFormProvider({ paymentReceiveId, ...props }) {
|
|||||||
paymentEntriesEditPage,
|
paymentEntriesEditPage,
|
||||||
accounts,
|
accounts,
|
||||||
customers,
|
customers,
|
||||||
|
branches,
|
||||||
|
|
||||||
isPaymentLoading,
|
isPaymentLoading,
|
||||||
isAccountsLoading,
|
isAccountsLoading,
|
||||||
isPaymentFetching,
|
isPaymentFetching,
|
||||||
isCustomersLoading,
|
isCustomersLoading,
|
||||||
|
isFeatureLoading,
|
||||||
|
isBranchesSuccess,
|
||||||
isNewMode,
|
isNewMode,
|
||||||
|
|
||||||
submitPayload,
|
submitPayload,
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import intl from 'react-intl-universal';
|
||||||
|
import {
|
||||||
|
Alignment,
|
||||||
|
Navbar,
|
||||||
|
NavbarGroup,
|
||||||
|
Button,
|
||||||
|
Classes,
|
||||||
|
} from '@blueprintjs/core';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import { useSetPrimaryBranchToForm } from './utils';
|
||||||
|
import { useFeatureCan } from 'hooks/state';
|
||||||
|
import { Icon, BranchSelect, FeatureCan } from 'components';
|
||||||
|
import { usePaymentReceiveFormContext } from './PaymentReceiveFormProvider';
|
||||||
|
import { Features } from 'common';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Payment receive from top bar.
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export default function PaymentReceiveFormTopBar() {
|
||||||
|
// Features guard.
|
||||||
|
const { featureCan } = useFeatureCan();
|
||||||
|
|
||||||
|
// Sets the primary branch to form.
|
||||||
|
useSetPrimaryBranchToForm();
|
||||||
|
|
||||||
|
// Can't display the navigation bar if branches feature is not enabled.
|
||||||
|
if (!featureCan(Features.Branches)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Navbar className={'navbar--dashboard-topbar'}>
|
||||||
|
<NavbarGroup align={Alignment.LEFT}>
|
||||||
|
<FeatureCan feature={Features.Branches}>
|
||||||
|
<PaymentReceiveFormSelectBranch />
|
||||||
|
</FeatureCan>
|
||||||
|
</NavbarGroup>
|
||||||
|
</Navbar>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function PaymentReceiveFormSelectBranch() {
|
||||||
|
// payment receive form context.
|
||||||
|
const { branches, isBranchesLoading } = usePaymentReceiveFormContext();
|
||||||
|
|
||||||
|
return isBranchesLoading ? (
|
||||||
|
<DetailsBarSkeletonBase className={Classes.SKELETON} />
|
||||||
|
) : (
|
||||||
|
<BranchSelect
|
||||||
|
name={'branch_id'}
|
||||||
|
branches={branches}
|
||||||
|
input={PaymentReceiveBranchSelectButton}
|
||||||
|
popoverProps={{ minimal: true }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function PaymentReceiveBranchSelectButton({ label }) {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
text={intl.get('invoice.branch_button.label', { label })}
|
||||||
|
minimal={true}
|
||||||
|
small={true}
|
||||||
|
icon={<Icon icon={'branch-16'} iconSize={16} />}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const DetailsBarSkeletonBase = styled.div`
|
||||||
|
letter-spacing: 10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-left: 10px;
|
||||||
|
font-size: 8px;
|
||||||
|
width: 140px;
|
||||||
|
height: 10px;
|
||||||
|
`;
|
||||||
@@ -1,13 +1,14 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useFormikContext } from 'formik';
|
import { useFormikContext } from 'formik';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { omit, pick } from 'lodash';
|
import { omit, pick, first } from 'lodash';
|
||||||
|
import { usePaymentReceiveFormContext } from './PaymentReceiveFormProvider';
|
||||||
import {
|
import {
|
||||||
defaultFastFieldShouldUpdate,
|
defaultFastFieldShouldUpdate,
|
||||||
transactionNumber,
|
transactionNumber,
|
||||||
transformToForm,
|
transformToForm,
|
||||||
safeSumBy,
|
safeSumBy,
|
||||||
orderingLinesIndexes
|
orderingLinesIndexes,
|
||||||
} from 'utils';
|
} from 'utils';
|
||||||
|
|
||||||
// Default payment receive entry.
|
// Default payment receive entry.
|
||||||
@@ -32,6 +33,7 @@ export const defaultPaymentReceive = {
|
|||||||
statement: '',
|
statement: '',
|
||||||
full_amount: '',
|
full_amount: '',
|
||||||
currency_code: '',
|
currency_code: '',
|
||||||
|
branch_id: '',
|
||||||
entries: [],
|
entries: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -46,8 +48,9 @@ export const defaultRequestPayment = {
|
|||||||
deposit_account_id: '',
|
deposit_account_id: '',
|
||||||
payment_date: '',
|
payment_date: '',
|
||||||
payment_receive_no: '',
|
payment_receive_no: '',
|
||||||
|
branch_id: '',
|
||||||
statement: '',
|
statement: '',
|
||||||
entries: []
|
entries: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -78,6 +81,7 @@ export const transformInvoicesNewPageEntries = (invoices) => [
|
|||||||
currency_code: invoice.currency_code,
|
currency_code: invoice.currency_code,
|
||||||
payment_amount: '',
|
payment_amount: '',
|
||||||
invoice_no: invoice.invoice_no,
|
invoice_no: invoice.invoice_no,
|
||||||
|
branch_id: invoice.branch_id,
|
||||||
total_payment_amount: invoice.payment_amount,
|
total_payment_amount: invoice.payment_amount,
|
||||||
})),
|
})),
|
||||||
];
|
];
|
||||||
@@ -162,3 +166,18 @@ export const transformFormToRequest = (form) => {
|
|||||||
entries: orderingLinesIndexes(entries),
|
entries: orderingLinesIndexes(entries),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useSetPrimaryBranchToForm = () => {
|
||||||
|
const { setFieldValue } = useFormikContext();
|
||||||
|
const { branches, isBranchesSuccess } = usePaymentReceiveFormContext();
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (isBranchesSuccess) {
|
||||||
|
const primaryBranch = branches.find((b) => b.primary) || first(branches);
|
||||||
|
|
||||||
|
if (primaryBranch) {
|
||||||
|
setFieldValue('branch_id', primaryBranch.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [isBranchesSuccess, setFieldValue, branches]);
|
||||||
|
};
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import ReceiptItemsEntriesEditor from './ReceiptItemsEntriesEditor';
|
|||||||
import ReceiptFormFloatingActions from './ReceiptFormFloatingActions';
|
import ReceiptFormFloatingActions from './ReceiptFormFloatingActions';
|
||||||
import ReceiptFormFooter from './ReceiptFormFooter';
|
import ReceiptFormFooter from './ReceiptFormFooter';
|
||||||
import ReceiptFormDialogs from './ReceiptFormDialogs';
|
import ReceiptFormDialogs from './ReceiptFormDialogs';
|
||||||
|
import ReceiptFormTopbar from './ReceiptFormTopbar';
|
||||||
|
|
||||||
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
||||||
import withSettings from 'containers/Settings/withSettings';
|
import withSettings from 'containers/Settings/withSettings';
|
||||||
@@ -157,6 +158,7 @@ function ReceiptForm({
|
|||||||
onSubmit={handleFormSubmit}
|
onSubmit={handleFormSubmit}
|
||||||
>
|
>
|
||||||
<Form>
|
<Form>
|
||||||
|
<ReceiptFormTopbar />
|
||||||
<ReceiptFromHeader />
|
<ReceiptFromHeader />
|
||||||
<ReceiptItemsEntriesEditor />
|
<ReceiptItemsEntriesEditor />
|
||||||
<ReceiptFormFooter />
|
<ReceiptFormFooter />
|
||||||
|
|||||||
@@ -4,12 +4,8 @@ import { DATATYPES_LENGTH } from 'common/dataTypes';
|
|||||||
import { isBlank } from 'utils';
|
import { isBlank } from 'utils';
|
||||||
|
|
||||||
const Schema = Yup.object().shape({
|
const Schema = Yup.object().shape({
|
||||||
customer_id: Yup.string()
|
customer_id: Yup.string().label(intl.get('customer_name_')).required(),
|
||||||
.label(intl.get('customer_name_'))
|
receipt_date: Yup.date().required().label(intl.get('receipt_date_')),
|
||||||
.required(),
|
|
||||||
receipt_date: Yup.date()
|
|
||||||
.required()
|
|
||||||
.label(intl.get('receipt_date_')),
|
|
||||||
receipt_number: Yup.string()
|
receipt_number: Yup.string()
|
||||||
.nullable()
|
.nullable()
|
||||||
.max(DATATYPES_LENGTH.STRING)
|
.max(DATATYPES_LENGTH.STRING)
|
||||||
@@ -29,6 +25,8 @@ const Schema = Yup.object().shape({
|
|||||||
.max(DATATYPES_LENGTH.TEXT)
|
.max(DATATYPES_LENGTH.TEXT)
|
||||||
.label(intl.get('note')),
|
.label(intl.get('note')),
|
||||||
closed: Yup.boolean(),
|
closed: Yup.boolean(),
|
||||||
|
branch_id: Yup.string(),
|
||||||
|
warehouse_id: Yup.string(),
|
||||||
entries: Yup.array().of(
|
entries: Yup.array().of(
|
||||||
Yup.object().shape({
|
Yup.object().shape({
|
||||||
quantity: Yup.number()
|
quantity: Yup.number()
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import {
|
|||||||
useAccounts,
|
useAccounts,
|
||||||
useSettingsReceipts,
|
useSettingsReceipts,
|
||||||
useCustomers,
|
useCustomers,
|
||||||
|
useWarehouses,
|
||||||
|
useBranches,
|
||||||
useItems,
|
useItems,
|
||||||
useCreateReceipt,
|
useCreateReceipt,
|
||||||
useEditReceipt,
|
useEditReceipt,
|
||||||
@@ -17,12 +19,9 @@ const ReceiptFormContext = createContext();
|
|||||||
*/
|
*/
|
||||||
function ReceiptFormProvider({ receiptId, ...props }) {
|
function ReceiptFormProvider({ receiptId, ...props }) {
|
||||||
// Fetch sale receipt details.
|
// Fetch sale receipt details.
|
||||||
const { data: receipt, isLoading: isReceiptLoading } = useReceipt(
|
const { data: receipt, isLoading: isReceiptLoading } = useReceipt(receiptId, {
|
||||||
receiptId,
|
enabled: !!receiptId,
|
||||||
{
|
});
|
||||||
enabled: !!receiptId,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
// Fetch accounts list.
|
// Fetch accounts list.
|
||||||
const { data: accounts, isLoading: isAccountsLoading } = useAccounts();
|
const { data: accounts, isLoading: isAccountsLoading } = useAccounts();
|
||||||
|
|
||||||
@@ -32,12 +31,38 @@ function ReceiptFormProvider({ receiptId, ...props }) {
|
|||||||
isLoading: isCustomersLoading,
|
isLoading: isCustomersLoading,
|
||||||
} = useCustomers({ page_size: 10000 });
|
} = useCustomers({ page_size: 10000 });
|
||||||
|
|
||||||
|
// Fetch warehouses list.
|
||||||
|
const {
|
||||||
|
data: warehouses,
|
||||||
|
isLoading: isWarehouesLoading,
|
||||||
|
isSuccess: isWarehousesSuccess,
|
||||||
|
} = useWarehouses();
|
||||||
|
|
||||||
|
// Fetches the branches list.
|
||||||
|
const {
|
||||||
|
data: branches,
|
||||||
|
isLoading: isBranchesLoading,
|
||||||
|
isSuccess: isBranchesSuccess,
|
||||||
|
} = useBranches();
|
||||||
|
|
||||||
// Filter all sellable items only.
|
// Filter all sellable items only.
|
||||||
const stringifiedFilterRoles = React.useMemo(
|
const stringifiedFilterRoles = React.useMemo(
|
||||||
() =>
|
() =>
|
||||||
JSON.stringify([
|
JSON.stringify([
|
||||||
{ index: 1, fieldKey: 'sellable', value: true, condition: '&&', comparator: 'equals', },
|
{
|
||||||
{ index: 2, fieldKey: 'active', value: true, condition: '&&', comparator: 'equals' },
|
index: 1,
|
||||||
|
fieldKey: 'sellable',
|
||||||
|
value: true,
|
||||||
|
condition: '&&',
|
||||||
|
comparator: 'equals',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: 2,
|
||||||
|
fieldKey: 'active',
|
||||||
|
value: true,
|
||||||
|
condition: '&&',
|
||||||
|
comparator: 'equals',
|
||||||
|
},
|
||||||
]),
|
]),
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
@@ -61,12 +86,16 @@ function ReceiptFormProvider({ receiptId, ...props }) {
|
|||||||
|
|
||||||
const isNewMode = !receiptId;
|
const isNewMode = !receiptId;
|
||||||
|
|
||||||
|
const isFeatureLoading = isWarehouesLoading || isBranchesLoading;
|
||||||
|
|
||||||
const provider = {
|
const provider = {
|
||||||
receiptId,
|
receiptId,
|
||||||
receipt,
|
receipt,
|
||||||
accounts,
|
accounts,
|
||||||
customers,
|
customers,
|
||||||
items,
|
items,
|
||||||
|
branches,
|
||||||
|
warehouses,
|
||||||
submitPayload,
|
submitPayload,
|
||||||
|
|
||||||
isNewMode,
|
isNewMode,
|
||||||
@@ -74,7 +103,12 @@ function ReceiptFormProvider({ receiptId, ...props }) {
|
|||||||
isAccountsLoading,
|
isAccountsLoading,
|
||||||
isCustomersLoading,
|
isCustomersLoading,
|
||||||
isItemsLoading,
|
isItemsLoading,
|
||||||
|
isWarehouesLoading,
|
||||||
|
isBranchesLoading,
|
||||||
|
isFeatureLoading,
|
||||||
isSettingLoading,
|
isSettingLoading,
|
||||||
|
isBranchesSuccess,
|
||||||
|
isWarehousesSuccess,
|
||||||
|
|
||||||
createReceiptMutate,
|
createReceiptMutate,
|
||||||
editReceiptMutate,
|
editReceiptMutate,
|
||||||
|
|||||||
127
src/containers/Sales/Receipts/ReceiptForm/ReceiptFormTopbar.js
Normal file
127
src/containers/Sales/Receipts/ReceiptForm/ReceiptFormTopbar.js
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import intl from 'react-intl-universal';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import {
|
||||||
|
Alignment,
|
||||||
|
Navbar,
|
||||||
|
NavbarGroup,
|
||||||
|
NavbarDivider,
|
||||||
|
Button,
|
||||||
|
Classes,
|
||||||
|
} from '@blueprintjs/core';
|
||||||
|
import {
|
||||||
|
useSetPrimaryWarehouseToForm,
|
||||||
|
useSetPrimaryBranchToForm,
|
||||||
|
} from './utils';
|
||||||
|
|
||||||
|
import { useFeatureCan } from 'hooks/state';
|
||||||
|
import { Icon, BranchSelect, FeatureCan, WarehouseSelect } from 'components';
|
||||||
|
import { useReceiptFormContext } from './ReceiptFormProvider';
|
||||||
|
import { Features } from 'common';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receipt form topbar .
|
||||||
|
* @returns {JSX.Element}
|
||||||
|
*/
|
||||||
|
export default function ReceiptFormTopbar() {
|
||||||
|
// Features guard.
|
||||||
|
const { featureCan } = useFeatureCan();
|
||||||
|
|
||||||
|
// Sets the primary warehouse to form.
|
||||||
|
useSetPrimaryWarehouseToForm();
|
||||||
|
|
||||||
|
// Sets the primary branch to form.
|
||||||
|
useSetPrimaryBranchToForm();
|
||||||
|
|
||||||
|
// Can't display the navigation bar if warehouses or branches feature is not enabled.
|
||||||
|
if (!featureCan(Features.Warehouses) || !featureCan(Features.Branches)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Navbar className={'navbar--dashboard-topbar'}>
|
||||||
|
<NavbarGroup align={Alignment.LEFT}>
|
||||||
|
<FeatureCan feature={Features.Branches}>
|
||||||
|
<ReceiptFormSelectBranch />
|
||||||
|
</FeatureCan>
|
||||||
|
{featureCan(Features.Warehouses) && featureCan(Features.Branches) && (
|
||||||
|
<NavbarDivider />
|
||||||
|
)}
|
||||||
|
<FeatureCan feature={Features.Warehouses}>
|
||||||
|
<ReceiptFormSelectWarehouse />
|
||||||
|
</FeatureCan>
|
||||||
|
</NavbarGroup>
|
||||||
|
</Navbar>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receipt select branch.
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function ReceiptFormSelectBranch() {
|
||||||
|
// Receipt form context.
|
||||||
|
const { branches, isBranchesLoading } = useReceiptFormContext();
|
||||||
|
|
||||||
|
return isBranchesLoading ? (
|
||||||
|
<DetailsBarSkeletonBase className={Classes.SKELETON} />
|
||||||
|
) : (
|
||||||
|
<BranchSelect
|
||||||
|
name={'branch_id'}
|
||||||
|
branches={branches}
|
||||||
|
input={ReceiptBranchSelectButton}
|
||||||
|
popoverProps={{ minimal: true }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receipt select warehouse.
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function ReceiptFormSelectWarehouse() {
|
||||||
|
// Receipt form context.
|
||||||
|
const { warehouses, isWarehouesLoading } = useReceiptFormContext();
|
||||||
|
|
||||||
|
return isWarehouesLoading ? (
|
||||||
|
<DetailsBarSkeletonBase className={Classes.SKELETON} />
|
||||||
|
) : (
|
||||||
|
<WarehouseSelect
|
||||||
|
name={'warehouse_id'}
|
||||||
|
warehouses={warehouses}
|
||||||
|
input={ReceiptWarehouseSelectButton}
|
||||||
|
popoverProps={{ minimal: true }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ReceiptBranchSelectButton({ label }) {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
text={intl.get('invoice.branch_button.label', { label })}
|
||||||
|
minimal={true}
|
||||||
|
small={true}
|
||||||
|
icon={<Icon icon={'branch-16'} iconSize={16} />}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ReceiptWarehouseSelectButton({ label }) {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
text={intl.get('invoice.warehouse_button.label', { label })}
|
||||||
|
minimal={true}
|
||||||
|
small={true}
|
||||||
|
icon={<Icon icon={'warehouse-16'} iconSize={16} />}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const DetailsBarSkeletonBase = styled.div`
|
||||||
|
letter-spacing: 10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-left: 10px;
|
||||||
|
font-size: 8px;
|
||||||
|
width: 140px;
|
||||||
|
height: 10px;
|
||||||
|
`;
|
||||||
@@ -3,13 +3,14 @@ import { useFormikContext } from 'formik';
|
|||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
import intl from 'react-intl-universal';
|
import intl from 'react-intl-universal';
|
||||||
import { omit } from 'lodash';
|
import { omit, first } from 'lodash';
|
||||||
import {
|
import {
|
||||||
defaultFastFieldShouldUpdate,
|
defaultFastFieldShouldUpdate,
|
||||||
transactionNumber,
|
transactionNumber,
|
||||||
repeatValue,
|
repeatValue,
|
||||||
transformToForm,
|
transformToForm,
|
||||||
} from 'utils';
|
} from 'utils';
|
||||||
|
import { useReceiptFormContext } from './ReceiptFormProvider';
|
||||||
import {
|
import {
|
||||||
updateItemsEntriesTotal,
|
updateItemsEntriesTotal,
|
||||||
ensureEntriesHaveEmptyLine,
|
ensureEntriesHaveEmptyLine,
|
||||||
@@ -36,6 +37,8 @@ export const defaultReceipt = {
|
|||||||
receipt_message: '',
|
receipt_message: '',
|
||||||
statement: '',
|
statement: '',
|
||||||
closed: '',
|
closed: '',
|
||||||
|
branch_id: '',
|
||||||
|
warehouse_id: '',
|
||||||
entries: [...repeatValue(defaultReceiptEntry, MIN_LINES_NUMBER)],
|
entries: [...repeatValue(defaultReceiptEntry, MIN_LINES_NUMBER)],
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -142,3 +145,34 @@ export const transformFormValuesToRequest = (values) => {
|
|||||||
closed: false,
|
closed: false,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useSetPrimaryWarehouseToForm = () => {
|
||||||
|
const { setFieldValue } = useFormikContext();
|
||||||
|
const { warehouses, isWarehousesSuccess } = useReceiptFormContext();
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (isWarehousesSuccess) {
|
||||||
|
const primaryWarehouse =
|
||||||
|
warehouses.find((b) => b.primary) || first(warehouses);
|
||||||
|
|
||||||
|
if (primaryWarehouse) {
|
||||||
|
setFieldValue('warehouse_id', primaryWarehouse.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [isWarehousesSuccess, setFieldValue, warehouses]);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useSetPrimaryBranchToForm = () => {
|
||||||
|
const { setFieldValue } = useFormikContext();
|
||||||
|
const { branches, isBranchesSuccess } = useReceiptFormContext();
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (isBranchesSuccess) {
|
||||||
|
const primaryBranch = branches.find((b) => b.primary) || first(branches);
|
||||||
|
|
||||||
|
if (primaryBranch) {
|
||||||
|
setFieldValue('branch_id', primaryBranch.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [isBranchesSuccess, setFieldValue, branches]);
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user