mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-17 21:30:31 +00:00
feature : Puschases & Sales / fix : tasks
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
import React, { useState, useMemo, useEffect, useCallback } from 'react';
|
||||
import { omit } from 'lodash';
|
||||
import { Button, Intent, Position, Tooltip } from '@blueprintjs/core';
|
||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
||||
|
||||
import CLASSES from 'components/classes';
|
||||
import DataTable from 'components/DataTable';
|
||||
import Icon from 'components/Icon';
|
||||
|
||||
import { compose, formattedAmount } from 'utils';
|
||||
import {
|
||||
InputGroupCell,
|
||||
MoneyFieldCell,
|
||||
@@ -14,7 +15,7 @@ import {
|
||||
} from 'components/DataTableCells';
|
||||
|
||||
import withItems from 'containers/Items/withItems';
|
||||
import { omit } from 'lodash';
|
||||
import { compose, formattedAmount } from 'utils';
|
||||
|
||||
const ActionsCellRenderer = ({
|
||||
row: { index },
|
||||
@@ -92,6 +93,7 @@ function EstimateTable({
|
||||
width: 40,
|
||||
disableResizing: true,
|
||||
disableSortBy: true,
|
||||
className: 'index',
|
||||
},
|
||||
{
|
||||
Header: formatMessage({ id: 'product_and_service' }),
|
||||
@@ -108,6 +110,7 @@ function EstimateTable({
|
||||
Cell: InputGroupCell,
|
||||
disableSortBy: true,
|
||||
className: 'description',
|
||||
width: 120,
|
||||
},
|
||||
|
||||
{
|
||||
@@ -123,7 +126,7 @@ function EstimateTable({
|
||||
accessor: 'rate',
|
||||
Cell: TotalEstimateCellRederer(MoneyFieldCell, 'rate'),
|
||||
disableSortBy: true,
|
||||
width: 150,
|
||||
width: 100,
|
||||
className: 'rate',
|
||||
},
|
||||
{
|
||||
@@ -230,8 +233,9 @@ function EstimateTable({
|
||||
updateData: handleUpdateData,
|
||||
removeRow: handleRemoveRow,
|
||||
}}
|
||||
className={CLASSES.DATATABLE_EDITOR}
|
||||
/>
|
||||
<div className={'mt1'}>
|
||||
<div className={'datatable-editor-actions mt1'}>
|
||||
<Button
|
||||
small={true}
|
||||
className={'button--secondary button--new-line'}
|
||||
|
||||
@@ -153,7 +153,6 @@ function EstimateActionsBar({
|
||||
const mapStateToProps = (state, props) => ({
|
||||
resourceName: 'sales_estimates',
|
||||
});
|
||||
|
||||
const withEstimateActionsBar = connect(mapStateToProps);
|
||||
|
||||
export default compose(
|
||||
|
||||
@@ -5,14 +5,13 @@ import React, {
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
|
||||
import * as Yup from 'yup';
|
||||
import { useFormik } from 'formik';
|
||||
import moment from 'moment';
|
||||
import { Intent, FormGroup, TextArea, Button } from '@blueprintjs/core';
|
||||
import { Intent, FormGroup, TextArea } from '@blueprintjs/core';
|
||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
||||
import { pick, omit } from 'lodash';
|
||||
import { queryCache } from 'react-query';
|
||||
import { pick } from 'lodash';
|
||||
import { Row, Col } from 'react-grid-system';
|
||||
|
||||
import EstimateFormHeader from './EstimateFormHeader';
|
||||
import EstimatesItemsTable from './EntriesItemsTable';
|
||||
@@ -103,13 +102,11 @@ const EstimateForm = ({
|
||||
.min(1)
|
||||
.max(1024)
|
||||
.label(formatMessage({ id: 'note' })),
|
||||
|
||||
terms_conditions: Yup.string()
|
||||
.trim()
|
||||
.min(1)
|
||||
.max(1024)
|
||||
.label(formatMessage({ id: 'note' })),
|
||||
|
||||
entries: Yup.array().of(
|
||||
Yup.object().shape({
|
||||
quantity: Yup.number().nullable(),
|
||||
@@ -176,7 +173,7 @@ const EstimateForm = ({
|
||||
index: index + 1,
|
||||
}));
|
||||
};
|
||||
// debugger;
|
||||
|
||||
const initialValues = useMemo(
|
||||
() => ({
|
||||
...(estimate
|
||||
@@ -200,14 +197,6 @@ const EstimateForm = ({
|
||||
[estimate, defaultInitialValues, defaultEstimate],
|
||||
);
|
||||
|
||||
// const initialValues = useMemo(
|
||||
// () => ({
|
||||
// ...defaultInitialValues,
|
||||
// entries: orderingProductsIndex(defaultInitialValues.entries),
|
||||
// }),
|
||||
// [defaultEstimate, defaultInitialValues, estimate],
|
||||
// );
|
||||
|
||||
const initialAttachmentFiles = useMemo(() => {
|
||||
return estimate && estimate.media
|
||||
? estimate.media.map((attach) => ({
|
||||
@@ -251,12 +240,8 @@ const EstimateForm = ({
|
||||
.then((response) => {
|
||||
AppToaster.show({
|
||||
message: formatMessage(
|
||||
{
|
||||
id: 'the_estimate_has_been_successfully_created',
|
||||
},
|
||||
{
|
||||
number: values.estimate_number,
|
||||
},
|
||||
{ id: 'the_estimate_has_been_successfully_created' },
|
||||
{ number: values.estimate_number },
|
||||
),
|
||||
intent: Intent.SUCCESS,
|
||||
});
|
||||
@@ -270,7 +255,7 @@ const EstimateForm = ({
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
console.log(formik.errors ,'ERROR');
|
||||
const handleSubmitClick = useCallback(
|
||||
(payload) => {
|
||||
setPayload(payload);
|
||||
@@ -313,9 +298,6 @@ const EstimateForm = ({
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
<form onSubmit={formik.handleSubmit}>
|
||||
@@ -325,36 +307,45 @@ const EstimateForm = ({
|
||||
onClickAddNewRow={handleClickAddNewRow}
|
||||
onClickClearAllLines={handleClearAllLines}
|
||||
formik={formik}
|
||||
// defaultRow={defaultEstimate}
|
||||
/>
|
||||
<FormGroup
|
||||
label={<T id={'customer_note'} />}
|
||||
className={'form-group--customer_note'}
|
||||
>
|
||||
<TextArea growVertically={true} {...formik.getFieldProps('note')} />
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
label={<T id={'terms_conditions'} />}
|
||||
className={'form-group--terms_conditions'}
|
||||
>
|
||||
<TextArea
|
||||
growVertically={true}
|
||||
{...formik.getFieldProps('terms_conditions')}
|
||||
/>
|
||||
</FormGroup>
|
||||
<Dragzone
|
||||
initialFiles={initialAttachmentFiles}
|
||||
onDrop={handleDropFiles}
|
||||
onDeleteFile={handleDeleteFile}
|
||||
hint={'Attachments: Maxiumum size: 20MB'}
|
||||
/>
|
||||
|
||||
<Row>
|
||||
<Col>
|
||||
<FormGroup
|
||||
label={<T id={'customer_note'} />}
|
||||
className={'form-group--customer_note'}
|
||||
>
|
||||
<TextArea
|
||||
growVertically={true}
|
||||
{...formik.getFieldProps('note')}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
label={<T id={'terms_conditions'} />}
|
||||
className={'form-group--terms_conditions'}
|
||||
>
|
||||
<TextArea
|
||||
growVertically={true}
|
||||
{...formik.getFieldProps('terms_conditions')}
|
||||
/>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
|
||||
<Col>
|
||||
<Dragzone
|
||||
initialFiles={initialAttachmentFiles}
|
||||
onDrop={handleDropFiles}
|
||||
onDeleteFile={handleDeleteFile}
|
||||
hint={'Attachments: Maxiumum size: 20MB'}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
</form>
|
||||
<EstimateFormFooter
|
||||
formik={formik}
|
||||
onSubmitClick={handleSubmitClick}
|
||||
estimate={estimate}
|
||||
onCancelClick={handleCancelClick}
|
||||
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -11,7 +11,7 @@ export default function EstimateFormFooter({
|
||||
estimate,
|
||||
}) {
|
||||
return (
|
||||
<div className={'estimate-form__floating-footer'}>
|
||||
<div className={'form__floating-footer'}>
|
||||
<Button
|
||||
disabled={isSubmitting}
|
||||
intent={Intent.PRIMARY}
|
||||
|
||||
@@ -68,13 +68,16 @@ function EstimateFormHeader({
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={'estimate-form'}>
|
||||
<div className={'estimate-form__primary-section'}>
|
||||
{/* customer name */}
|
||||
<div className={'page-form page-form--estimate'}>
|
||||
<div className={'page-form__primary-section'}>
|
||||
<FormGroup
|
||||
label={<T id={'customer_name'} />}
|
||||
inline={true}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
className={classNames(
|
||||
'form-group--select-list',
|
||||
'form-group--customer',
|
||||
Classes.FILL,
|
||||
)}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
intent={errors.customer_id && touched.customer_id && Intent.DANGER}
|
||||
helperText={
|
||||
@@ -94,17 +97,18 @@ function EstimateFormHeader({
|
||||
labelProp={'display_name'}
|
||||
/>
|
||||
</FormGroup>
|
||||
{/* estimate_date */}
|
||||
<Row>
|
||||
<Col
|
||||
|
||||
// md={9} push={{ md: 3 }}
|
||||
>
|
||||
<Row>
|
||||
<Col>
|
||||
<FormGroup
|
||||
label={<T id={'estimate_date'} />}
|
||||
inline={true}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
className={classNames(
|
||||
'form-group--select-list',
|
||||
Classes.FILL,
|
||||
'form-group--estimate-date',
|
||||
)}
|
||||
intent={
|
||||
errors.estimate_date && touched.estimate_date && Intent.DANGER
|
||||
}
|
||||
@@ -120,14 +124,15 @@ function EstimateFormHeader({
|
||||
/>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
<Col
|
||||
|
||||
// md={3} pull={{ md: 9 }}
|
||||
>
|
||||
<Col>
|
||||
<FormGroup
|
||||
label={<T id={'expiration_date'} />}
|
||||
inline={true}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
className={classNames(
|
||||
'form-group--select-list',
|
||||
'form-group--expiration-date',
|
||||
Classes.FILL,
|
||||
)}
|
||||
intent={
|
||||
errors.expiration_date &&
|
||||
touched.expiration_date &&
|
||||
@@ -147,11 +152,12 @@ function EstimateFormHeader({
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
{/* Estimate */}
|
||||
|
||||
{/*- Estimate -*/}
|
||||
<FormGroup
|
||||
label={<T id={'estimate'} />}
|
||||
inline={true}
|
||||
className={('form-group--estimate', Classes.FILL)}
|
||||
className={('form-group--estimate-number', Classes.FILL)}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
intent={
|
||||
errors.estimate_number && touched.estimate_number && Intent.DANGER
|
||||
@@ -168,6 +174,7 @@ function EstimateFormHeader({
|
||||
{...getFieldProps('estimate_number')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup
|
||||
label={<T id={'reference'} />}
|
||||
inline={true}
|
||||
|
||||
@@ -33,6 +33,7 @@ function Estimates({
|
||||
requestFetchCustomers({}),
|
||||
);
|
||||
|
||||
//
|
||||
const handleFormSubmit = useCallback(
|
||||
(payload) => {
|
||||
payload.redirect && history.push('/estimates');
|
||||
|
||||
@@ -2,22 +2,25 @@ import { connect } from 'react-redux';
|
||||
import { getResourceViews } from 'store/customViews/customViews.selectors';
|
||||
import {
|
||||
getEstimateCurrentPageFactory,
|
||||
getEstimatesTableQuery,
|
||||
getEstimatesTableQueryFactory,
|
||||
getEstimatesPaginationMetaFactory,
|
||||
} from 'store/Estimate/estimates.selectors';
|
||||
|
||||
export default (mapState) => {
|
||||
const getEstimatesItems = getEstimateCurrentPageFactory();
|
||||
const getEstimatesPaginationMeta = getEstimatesPaginationMetaFactory();
|
||||
const getEstimatesTableQuery = getEstimatesTableQueryFactory();
|
||||
|
||||
const mapStateToProps = (state, props) => {
|
||||
const query = getEstimatesTableQuery(state, props);
|
||||
|
||||
const mapped = {
|
||||
estimatesCurrentPage: getEstimatesItems(state, props, query),
|
||||
estimateViews: getResourceViews(state, props, 'sales_estimates'),
|
||||
estimateItems: state.sales_estimates.items,
|
||||
estimateItems: state.salesEstimates.items,
|
||||
estimateTableQuery: query,
|
||||
estimatesPageination: getEstimatesPaginationMeta(state, props, query),
|
||||
estimatesLoading: state.sales_estimates.loading,
|
||||
estimatesLoading: state.salesEstimates.loading,
|
||||
};
|
||||
return mapState ? mapState(mapped, state, props) : mapped;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user