feat(customer & vendor): add branch.

This commit is contained in:
elforjani13
2022-03-09 22:03:21 +02:00
parent 37f8662cc5
commit c1ad349f6b
9 changed files with 144 additions and 29 deletions

View File

@@ -3,32 +3,33 @@ import classNames from 'classnames';
import { FormGroup, Position, Classes, ControlGroup } from '@blueprintjs/core'; import { FormGroup, Position, Classes, ControlGroup } from '@blueprintjs/core';
import { DateInput } from '@blueprintjs/datetime'; import { DateInput } from '@blueprintjs/datetime';
import { FastField, ErrorMessage } from 'formik'; import { FastField, ErrorMessage } from 'formik';
import { FFormGroup } from '../../../components/Forms';
import moment from 'moment'; import moment from 'moment';
import { Features } from 'common';
import { import {
MoneyInputGroup, MoneyInputGroup,
InputPrependText, InputPrependText,
CurrencySelectList, CurrencySelectList,
BranchSelect,
BranchSelectButton,
FeatureCan,
Row, Row,
Col, Col,
} from 'components'; } from 'components';
import { FormattedMessage as T } from 'components'; import { FormattedMessage as T } from 'components';
import { useCustomerFormContext } from './CustomerFormProvider'; import { useCustomerFormContext } from './CustomerFormProvider';
import { useSetPrimaryBranchToForm } from './utils';
import { import { momentFormatter, tansformDateValue, inputIntent } from 'utils';
momentFormatter,
tansformDateValue,
inputIntent,
} from 'utils';
/** /**
* Customer financial panel. * Customer financial panel.
*/ */
export default function CustomerFinancialPanel() { export default function CustomerFinancialPanel() {
const { const { currencies, customerId, branches } = useCustomerFormContext();
currencies,
customerId // Sets the primary branch to form.
} = useCustomerFormContext(); useSetPrimaryBranchToForm();
return ( return (
<div className={'tab-panel--financial'}> <div className={'tab-panel--financial'}>
@@ -62,12 +63,7 @@ export default function CustomerFinancialPanel() {
{/*------------ Opening balance -----------*/} {/*------------ Opening balance -----------*/}
<FastField name={'opening_balance'}> <FastField name={'opening_balance'}>
{({ {({ form, field, field: { value }, meta: { error, touched } }) => (
form,
field,
field: { value },
meta: { error, touched },
}) => (
<FormGroup <FormGroup
label={<T id={'opening_balance'} />} label={<T id={'opening_balance'} />}
className={classNames( className={classNames(
@@ -92,6 +88,23 @@ export default function CustomerFinancialPanel() {
)} )}
</FastField> </FastField>
{/*------------ Opening branch -----------*/}
<FeatureCan feature={Features.Branches}>
<FFormGroup
label={<T id={'customer.label.opening_branch'} />}
name={'opening_balance_branch_id'}
inline={true}
className={classNames('form-group--select-list', Classes.FILL)}
>
<BranchSelect
name={'opening_balance_branch_id'}
branches={branches}
input={BranchSelectButton}
popoverProps={{ minimal: true }}
/>
</FFormGroup>
</FeatureCan>
{/*------------ Currency -----------*/} {/*------------ Currency -----------*/}
<FastField name={'currency_code'}> <FastField name={'currency_code'}>
{({ form, field: { value }, meta: { error, touched } }) => ( {({ form, field: { value }, meta: { error, touched } }) => (

View File

@@ -42,6 +42,7 @@ const Schema = Yup.object().shape({
opening_balance: Yup.number().nullable(), opening_balance: Yup.number().nullable(),
currency_code: Yup.string(), currency_code: Yup.string(),
opening_balance_at: Yup.date(), opening_balance_at: Yup.date(),
opening_balance_branch_id: Yup.string(),
}); });
export const CreateCustomerForm = Schema; export const CreateCustomerForm = Schema;

View File

@@ -6,15 +6,21 @@ import {
useCreateCustomer, useCreateCustomer,
useEditCustomer, useEditCustomer,
useContact, useContact,
useBranches,
} from 'hooks/query'; } from 'hooks/query';
import { Features } from 'common';
import { useFeatureCan } from 'hooks/state';
const CustomerFormContext = createContext(); const CustomerFormContext = createContext();
function CustomerFormProvider({ customerId, ...props }) { function CustomerFormProvider({ query, customerId, ...props }) {
const { state } = useLocation(); const { state } = useLocation();
const contactId = state?.action; const contactId = state?.action;
// Features guard.
const { featureCan } = useFeatureCan();
const isBranchFeatureCan = featureCan(Features.Branches);
// Handle fetch customer details. // Handle fetch customer details.
const { data: customer, isLoading: isCustomerLoading } = useCustomer( const { data: customer, isLoading: isCustomerLoading } = useCustomer(
customerId, customerId,
@@ -28,6 +34,13 @@ function CustomerFormProvider({ customerId, ...props }) {
// Handle fetch Currencies data table // Handle fetch Currencies data table
const { data: currencies, isLoading: isCurrenciesLoading } = useCurrencies(); const { data: currencies, isLoading: isCurrenciesLoading } = useCurrencies();
// Fetches the branches list.
const {
data: branches,
isLoading: isBranchesLoading,
isSuccess: isBranchesSuccess,
} = useBranches(query, { enabled: isBranchFeatureCan });
// Form submit payload. // Form submit payload.
const [submitPayload, setSubmitPayload] = useState({}); const [submitPayload, setSubmitPayload] = useState({});
@@ -38,18 +51,20 @@ function CustomerFormProvider({ customerId, ...props }) {
const isNewMode = contactId || !customerId; const isNewMode = contactId || !customerId;
const isFormLoading = const isFormLoading =
isCustomerLoading || isCurrenciesLoading || isContactLoading; isCustomerLoading || isCurrenciesLoading || isBranchesLoading;
const provider = { const provider = {
customerId, customerId,
customer, customer,
currencies, currencies,
branches,
contactDuplicate, contactDuplicate,
submitPayload, submitPayload,
isNewMode, isNewMode,
isCustomerLoading, isCustomerLoading,
isCurrenciesLoading, isCurrenciesLoading,
isBranchesSuccess,
isFormLoading, isFormLoading,
setSubmitPayload, setSubmitPayload,

View File

@@ -1,5 +1,9 @@
import React from 'react';
import moment from 'moment'; import moment from 'moment';
import { useFormikContext } from 'formik';
import { first } from 'lodash';
import { useCustomerFormContext } from './CustomerFormProvider';
export const defaultInitialValues = { export const defaultInitialValues = {
customer_type: 'business', customer_type: 'business',
@@ -35,4 +39,20 @@ export const defaultInitialValues = {
opening_balance: '', opening_balance: '',
currency_code: '', currency_code: '',
opening_balance_at: moment(new Date()).format('YYYY-MM-DD'), opening_balance_at: moment(new Date()).format('YYYY-MM-DD'),
opening_balance_branch_id: '',
};
export const useSetPrimaryBranchToForm = () => {
const { setFieldValue } = useFormikContext();
const { branches, isBranchesSuccess } = useCustomerFormContext();
React.useEffect(() => {
if (isBranchesSuccess) {
const primaryBranch = branches.find((b) => b.primary) || first(branches);
if (primaryBranch) {
setFieldValue('opening_balance_branch_id', primaryBranch.id);
}
}
}, [isBranchesSuccess, setFieldValue, branches]);
}; };

View File

@@ -1,17 +1,23 @@
import React from 'react'; import React from 'react';
import moment from 'moment';
import classNames from 'classnames'; import classNames from 'classnames';
import { FormGroup, ControlGroup, Position, Classes } from '@blueprintjs/core'; import { FormGroup, ControlGroup, Position, Classes } from '@blueprintjs/core';
import { DateInput } from '@blueprintjs/datetime'; import { DateInput } from '@blueprintjs/datetime';
import { FastField, ErrorMessage } from 'formik'; import { FastField, ErrorMessage } from 'formik';
import moment from 'moment'; import { FFormGroup } from '../../../components/Forms';
import { Features } from 'common';
import { import {
MoneyInputGroup, MoneyInputGroup,
InputPrependText, InputPrependText,
CurrencySelectList, CurrencySelectList,
BranchSelect,
BranchSelectButton,
FeatureCan,
Row, Row,
Col, Col,
} from 'components'; } from 'components';
import { FormattedMessage as T } from 'components'; import { FormattedMessage as T } from 'components';
import { useSetPrimaryBranchToForm } from './utils';
import { momentFormatter, tansformDateValue, inputIntent } from 'utils'; import { momentFormatter, tansformDateValue, inputIntent } from 'utils';
import { useVendorFormContext } from './VendorFormProvider'; import { useVendorFormContext } from './VendorFormProvider';
@@ -19,7 +25,10 @@ import { useVendorFormContext } from './VendorFormProvider';
* Vendor Finaniceal Panel Tab. * Vendor Finaniceal Panel Tab.
*/ */
export default function VendorFinanicalPanelTab() { export default function VendorFinanicalPanelTab() {
const { vendorId, currencies } = useVendorFormContext(); const { vendorId, currencies, branches } = useVendorFormContext();
// Sets the primary branch to form.
useSetPrimaryBranchToForm();
return ( return (
<div className={'tab-panel--financial'}> <div className={'tab-panel--financial'}>
@@ -80,6 +89,23 @@ export default function VendorFinanicalPanelTab() {
)} )}
</FastField> </FastField>
{/*------------ Opening branch -----------*/}
<FeatureCan feature={Features.Branches}>
<FFormGroup
label={<T id={'vendor.label.opening_branch'} />}
name={'opening_balance_branch_id'}
inline={true}
className={classNames('form-group--select-list', Classes.FILL)}
>
<BranchSelect
name={'opening_balance_branch_id'}
branches={branches}
input={BranchSelectButton}
popoverProps={{ minimal: true }}
/>
</FFormGroup>
</FeatureCan>
{/*------------ Currency -----------*/} {/*------------ Currency -----------*/}
<FastField name={'currency_code'}> <FastField name={'currency_code'}>
{({ form, field: { value }, meta: { error, touched } }) => ( {({ form, field: { value }, meta: { error, touched } }) => (

View File

@@ -6,10 +6,7 @@ const Schema = Yup.object().shape({
first_name: Yup.string().trim(), first_name: Yup.string().trim(),
last_name: Yup.string().trim(), last_name: Yup.string().trim(),
company_name: Yup.string().trim(), company_name: Yup.string().trim(),
display_name: Yup.string() display_name: Yup.string().trim().required().label(intl.get('display_name_')),
.trim()
.required()
.label(intl.get('display_name_')),
email: Yup.string().email().nullable(), email: Yup.string().email().nullable(),
work_phone: Yup.number(), work_phone: Yup.number(),
@@ -38,6 +35,7 @@ const Schema = Yup.object().shape({
opening_balance: Yup.number().nullable(), opening_balance: Yup.number().nullable(),
currency_code: Yup.string(), currency_code: Yup.string(),
opening_balance_at: Yup.date(), opening_balance_at: Yup.date(),
opening_balance_branch_id: Yup.string(),
}); });
export const CreateVendorFormSchema = Schema; export const CreateVendorFormSchema = Schema;

View File

@@ -8,18 +8,24 @@ import {
useCurrencies, useCurrencies,
useCreateVendor, useCreateVendor,
useEditVendor, useEditVendor,
useBranches,
} from 'hooks/query'; } from 'hooks/query';
import { Features } from 'common';
import { useFeatureCan } from 'hooks/state';
const VendorFormContext = createContext(); const VendorFormContext = createContext();
/** /**
* Vendor form provider. * Vendor form provider.
*/ */
function VendorFormProvider({ vendorId, ...props }) { function VendorFormProvider({ query, vendorId, ...props }) {
const { state } = useLocation(); const { state } = useLocation();
const contactId = state?.action; const contactId = state?.action;
// Features guard.
const { featureCan } = useFeatureCan();
const isBranchFeatureCan = featureCan(Features.Branches);
// Handle fetch Currencies data table // Handle fetch Currencies data table
const { data: currencies, isLoading: isCurrenciesLoading } = useCurrencies(); const { data: currencies, isLoading: isCurrenciesLoading } = useCurrencies();
@@ -33,6 +39,14 @@ function VendorFormProvider({ vendorId, ...props }) {
contactId, contactId,
{ enabled: !!contactId }, { enabled: !!contactId },
); );
// Fetches the branches list.
const {
data: branches,
isLoading: isBranchesLoading,
isSuccess: isBranchesSuccess,
} = useBranches(query, { enabled: isBranchFeatureCan });
// Create and edit vendor mutations. // Create and edit vendor mutations.
const { mutateAsync: createVendorMutate } = useCreateVendor(); const { mutateAsync: createVendorMutate } = useCreateVendor();
const { mutateAsync: editVendorMutate } = useEditVendor(); const { mutateAsync: editVendorMutate } = useEditVendor();
@@ -44,17 +58,22 @@ function VendorFormProvider({ vendorId, ...props }) {
const isNewMode = contactId || !vendorId; const isNewMode = contactId || !vendorId;
const isFormLoading = const isFormLoading =
isVendorLoading || isContactLoading || isCurrenciesLoading; isVendorLoading ||
isContactLoading ||
isCurrenciesLoading ||
isBranchesLoading;
const provider = { const provider = {
vendorId, vendorId,
currencies, currencies,
vendor, vendor,
branches,
contactDuplicate: { ...omit(contactDuplicate, ['opening_balance_at']) }, contactDuplicate: { ...omit(contactDuplicate, ['opening_balance_at']) },
submitPayload, submitPayload,
isNewMode, isNewMode,
isFormLoading, isFormLoading,
isBranchesSuccess,
createVendorMutate, createVendorMutate,
editVendorMutate, editVendorMutate,

View File

@@ -1,4 +1,9 @@
import React from 'react';
import moment from 'moment'; import moment from 'moment';
import { useFormikContext } from 'formik';
import { first } from 'lodash';
import { useVendorFormContext } from './VendorFormProvider';
export const defaultInitialValues = { export const defaultInitialValues = {
salutation: '', salutation: '',
@@ -33,4 +38,20 @@ export const defaultInitialValues = {
opening_balance: '', opening_balance: '',
currency_code: '', currency_code: '',
opening_balance_at: moment(new Date()).format('YYYY-MM-DD'), opening_balance_at: moment(new Date()).format('YYYY-MM-DD'),
opening_balance_branch_id: '',
};
export const useSetPrimaryBranchToForm = () => {
const { setFieldValue } = useFormikContext();
const { branches, isBranchesSuccess } = useVendorFormContext();
React.useEffect(() => {
if (isBranchesSuccess) {
const primaryBranch = branches.find((b) => b.primary) || first(branches);
if (primaryBranch) {
setFieldValue('opening_balance_branch_id', primaryBranch.id);
}
}
}, [isBranchesSuccess, setFieldValue, branches]);
}; };

View File

@@ -1895,5 +1895,7 @@
"vendor_opening_balance.success_message": "The opening balance of the given vendor has been changed successfully.", "vendor_opening_balance.success_message": "The opening balance of the given vendor has been changed successfully.",
"vendor_opening_balance.label": "Edit Vendor Opening Balance", "vendor_opening_balance.label": "Edit Vendor Opening Balance",
"vendor_opening_balance.label.opening_balance": "Opening balance", "vendor_opening_balance.label.opening_balance": "Opening balance",
"vendor_opening_balance.label.opening_balance_at": "Opening balance at" "vendor_opening_balance.label.opening_balance_at": "Opening balance at",
"customer.label.opening_branch": "Opening Balance Branch",
"vendor.label.opening_branch": "Opening Balance Branch"
} }