WIP: Feature JournalNumber dialog / Fix: ItemCategory & EditMakeJournal & Expenses

This commit is contained in:
elforjani3
2020-10-19 19:53:10 +02:00
parent 00ba1bb75e
commit d804007596
12 changed files with 413 additions and 94 deletions

View File

@@ -5,6 +5,7 @@ import ItemCategoryDialog from 'containers/Dialogs/ItemCategoryDialog';
import CurrencyDialog from 'containers/Dialogs/CurrencyDialog'; import CurrencyDialog from 'containers/Dialogs/CurrencyDialog';
import InviteUserDialog from 'containers/Dialogs/InviteUserDialog'; import InviteUserDialog from 'containers/Dialogs/InviteUserDialog';
import ExchangeRateDialog from 'containers/Dialogs/ExchangeRateDialog'; import ExchangeRateDialog from 'containers/Dialogs/ExchangeRateDialog';
import JournalNumberDailog from 'containers/Dialogs/JournalNumberDailog';
export default function DialogsContainer() { export default function DialogsContainer() {
return ( return (
@@ -15,6 +16,7 @@ export default function DialogsContainer() {
<ItemCategoryDialog /> <ItemCategoryDialog />
<AccountFormDialog /> <AccountFormDialog />
{/* <UserFormDialog /> */} {/* <UserFormDialog /> */}
<JournalNumberDailog />
</div> </div>
); );
} }

View File

@@ -6,10 +6,11 @@ export default function MakeJournalEntriesFooter({
formik: { isSubmitting }, formik: { isSubmitting },
onSubmitClick, onSubmitClick,
onCancelClick, onCancelClick,
manualJournal,
}) { }) {
return ( return (
<div> <div>
<div class='form__floating-footer'> <div class="form__floating-footer">
<Button <Button
disabled={isSubmitting} disabled={isSubmitting}
intent={Intent.PRIMARY} intent={Intent.PRIMARY}
@@ -18,7 +19,11 @@ export default function MakeJournalEntriesFooter({
onSubmitClick({ publish: true, redirect: true }); onSubmitClick({ publish: true, redirect: true });
}} }}
> >
<T id={'save'} /> {manualJournal && manualJournal.id ? (
<T id={'edit'} />
) : (
<T id={'save'} />
)}
</Button> </Button>
<Button <Button
@@ -49,7 +54,7 @@ export default function MakeJournalEntriesFooter({
onCancelClick && onCancelClick(); onCancelClick && onCancelClick();
}} }}
> >
<T id={'cancel'}/> <T id={'cancel'} />
</Button> </Button>
</div> </div>
</div> </div>

View File

@@ -34,7 +34,8 @@ const ERROR = {
VENDORS_NOT_WITH_PAYABLE_ACCOUNT: 'VENDORS.NOT.WITH.PAYABLE.ACCOUNT', VENDORS_NOT_WITH_PAYABLE_ACCOUNT: 'VENDORS.NOT.WITH.PAYABLE.ACCOUNT',
PAYABLE_ENTRIES_HAS_NO_VENDORS: 'PAYABLE.ENTRIES.HAS.NO.VENDORS', PAYABLE_ENTRIES_HAS_NO_VENDORS: 'PAYABLE.ENTRIES.HAS.NO.VENDORS',
RECEIVABLE_ENTRIES_HAS_NO_CUSTOMERS: 'RECEIVABLE.ENTRIES.HAS.NO.CUSTOMERS', RECEIVABLE_ENTRIES_HAS_NO_CUSTOMERS: 'RECEIVABLE.ENTRIES.HAS.NO.CUSTOMERS',
CREDIT_DEBIT_SUMATION_SHOULD_NOT_EQUAL_ZERO:'CREDIT.DEBIT.SUMATION.SHOULD.NOT.EQUAL.ZERO' CREDIT_DEBIT_SUMATION_SHOULD_NOT_EQUAL_ZERO:
'CREDIT.DEBIT.SUMATION.SHOULD.NOT.EQUAL.ZERO',
}; };
/** /**
@@ -58,7 +59,6 @@ function MakeJournalEntriesForm({
onFormSubmit, onFormSubmit,
onCancelForm, onCancelForm,
}) { }) {
const { formatMessage } = useIntl(); const { formatMessage } = useIntl();
const { const {
setFiles, setFiles,
@@ -75,7 +75,6 @@ function MakeJournalEntriesForm({
setFiles(_files.filter((file) => file.uploaded === false)); setFiles(_files.filter((file) => file.uploaded === false));
}, []); }, []);
const savedMediaIds = useRef([]); const savedMediaIds = useRef([]);
const clearSavedMediaIds = () => { const clearSavedMediaIds = () => {
savedMediaIds.current = []; savedMediaIds.current = [];
@@ -140,6 +139,7 @@ function MakeJournalEntriesForm({
const defaultEntry = useMemo( const defaultEntry = useMemo(
() => ({ () => ({
index: 0,
account_id: null, account_id: null,
credit: 0, credit: 0,
debit: 0, debit: 0,
@@ -262,7 +262,7 @@ function MakeJournalEntriesForm({
}, },
onSubmit: async (values, { setErrors, setSubmitting, resetForm }) => { onSubmit: async (values, { setErrors, setSubmitting, resetForm }) => {
const entries = values.entries.filter( const entries = values.entries.filter(
(entry) => entry.credit || entry.debit, (entry) => entry.debit || entry.credit,
); );
const getTotal = (type = 'credit') => { const getTotal = (type = 'credit') => {
return entries.reduce((total, item) => { return entries.reduce((total, item) => {
@@ -413,6 +413,7 @@ function MakeJournalEntriesForm({
formik={formik} formik={formik}
onSubmitClick={handleSubmitClick} onSubmitClick={handleSubmitClick}
onCancelClick={handleCancelClick} onCancelClick={handleCancelClick}
manualJournal={manualJournal}
/> />
</form> </form>

View File

@@ -5,6 +5,7 @@ import {
Intent, Intent,
Position, Position,
Classes, Classes,
Button,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import { DateInput } from '@blueprintjs/datetime'; import { DateInput } from '@blueprintjs/datetime';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'react-intl';
@@ -18,11 +19,18 @@ import {
Hint, Hint,
FieldHint, FieldHint,
FieldRequiredHint, FieldRequiredHint,
Icon,
} from 'components'; } from 'components';
import withDialogActions from 'containers/Dialog/withDialogActions';
export default function MakeJournalEntriesHeader({ import { compose } from 'utils';
function MakeJournalEntriesHeader({
formik: { errors, touched, values, setFieldValue, getFieldProps }, formik: { errors, touched, values, setFieldValue, getFieldProps },
// #withDialog
openDialog,
}) { }) {
const handleDateChange = useCallback( const handleDateChange = useCallback(
(date) => { (date) => {
@@ -31,6 +39,9 @@ export default function MakeJournalEntriesHeader({
}, },
[setFieldValue], [setFieldValue],
); );
const handleJournalNumberChange = useCallback(() => {
openDialog('journalNumber-form', {});
}, [openDialog]);
return ( return (
<div class="make-journal-entries__header"> <div class="make-journal-entries__header">
@@ -62,7 +73,15 @@ export default function MakeJournalEntriesHeader({
/> />
</FormGroup> </FormGroup>
</Col> </Col>
<Col width={50}>
{/* <FormGroup> */}
<Button
className={classNames('btn', Classes.SMALL)}
icon={<Icon icon="setting" />}
onClick={handleJournalNumberChange}
/>
{/* </FormGroup> */}
</Col>
<Col width={220}> <Col width={220}>
<FormGroup <FormGroup
label={<T id={'date'} />} label={<T id={'date'} />}
@@ -153,3 +172,5 @@ export default function MakeJournalEntriesHeader({
</div> </div>
); );
} }
export default compose(withDialogActions)(MakeJournalEntriesHeader);

View File

@@ -78,15 +78,9 @@ function ItemCategoryDialog({
.required() .required()
.label(formatMessage({ id: 'category_name_' })), .label(formatMessage({ id: 'category_name_' })),
parent_category_id: Yup.string().nullable(), parent_category_id: Yup.string().nullable(),
cost_account_id: Yup.number() cost_account_id: Yup.number().nullable(),
.required() sell_account_id: Yup.number().nullable(),
.label(formatMessage({ id: 'cost_account_' })), inventory_account_id: Yup.number(),
sell_account_id: Yup.number()
.required()
.label(formatMessage({ id: 'sell_account_' })),
inventory_account_id: Yup.number()
.required()
.label(formatMessage({ id: 'inventory_account_' })),
description: Yup.string().trim().nullable(), description: Yup.string().trim().nullable(),
}); });
@@ -122,7 +116,7 @@ function ItemCategoryDialog({
onSubmit: (values, { setSubmitting }) => { onSubmit: (values, { setSubmitting }) => {
const afterSubmit = () => { const afterSubmit = () => {
closeDialog(dialogName); closeDialog(dialogName);
queryCache.invalidateQueries('items-categories-table'); queryCache.invalidateQueries('items-categories-list');
queryCache.invalidateQueries('accounts-list'); queryCache.invalidateQueries('accounts-list');
}; };
if (payload.action === 'edit') { if (payload.action === 'edit') {

View File

@@ -0,0 +1,71 @@
import React, { useEffect, useCallback, useMemo } from 'react';
import { FormattedMessage as T, useIntl } from 'react-intl';
import { useQuery, queryCache } from 'react-query';
import { Dialog } from 'components';
import withDialogActions from 'containers/Dialog/withDialogActions';
import withDialogRedux from 'components/DialogReduxConnect';
import withSettingsActions from 'containers/Settings/withSettingsActions';
import withSettings from 'containers/Settings/withSettings';
import ReferenceNumberForm from 'containers/JournalNumber/ReferenceNumberForm';
import classNames from 'classnames';
import { connect } from 'react-redux';
import { compose, optionsMapToArray } from 'utils';
function JournalNumberDailog({
dialogName,
payload,
isOpen,
// #withSettingsActions
requestSubmitOptions,
// #withDialogActions
closeDialog,
}) {
// Handles dialog close.
const handleClose = useCallback(() => {
closeDialog(dialogName);
}, [closeDialog, dialogName]);
const handleSubmitForm = useCallback(() => {});
// Handle dialog on closed.
// const onDialogClosed = useCallback(() => {
// resetForm();
// }, [resetForm]);
return (
<Dialog
name={dialogName}
// isLoading={}
title={<T id={'journal_number_settings'} />}
autoFocus={true}
canEscapeKeyClose={true}
isOpen={isOpen}
onClose={handleClose}
>
<ReferenceNumberForm
onSubmit={handleSubmitForm}
initialNumber={'1000'}
initialPrefix={'A'}
onClose={handleClose}
groupName={'manual_journals'}
/>
</Dialog>
);
}
const mapStateToProps = (state, props) => ({
dialogName: 'journalNumber-form',
journalNumberId: props?.payload?.id || null,
});
const withJournalNumberDailog = connect(mapStateToProps);
export default compose(
withDialogRedux(null, 'journalNumber-form'),
withJournalNumberDailog,
withDialogActions,
withSettingsActions,
)(JournalNumberDailog);

View File

@@ -164,10 +164,10 @@ function ExpenseForm({
...expense.categories.map((category) => ({ ...expense.categories.map((category) => ({
...pick(category, Object.keys(defaultCategory)), ...pick(category, Object.keys(defaultCategory)),
})), })),
...repeatValue( // ...repeatValue(
defaultCategory, // defaultCategory,
Math.max(MIN_LINES_NUMBER - expense.categories.length, 0), // Math.max(MIN_LINES_NUMBER - expense.categories.length, 0),
), // ),
], ],
} }
: { : {
@@ -226,10 +226,12 @@ function ExpenseForm({
}); });
return; return;
} }
const categories = values.categories.filter( const categories = values.categories.filter(
(category) => (category) =>
category.amount && category.index && category.expense_account_id, category.amount && category.index && category.expense_account_id,
); );
const form = { const form = {
...values, ...values,
publish: payload.publish, publish: payload.publish,
@@ -329,10 +331,21 @@ function ExpenseForm({
const handleClearAllLines = () => { const handleClearAllLines = () => {
formik.setFieldValue( formik.setFieldValue(
'categories', 'categories',
orderingCategoriesIndex([...repeatValue(defaultCategory, MIN_LINES_NUMBER)]), orderingCategoriesIndex([
...repeatValue(defaultCategory, MIN_LINES_NUMBER),
]),
); );
}; };
const categories = formik.values.categories.filter(
(category) =>
category.amount && category.index && category.expense_account_id,
);
console.log(categories, 'V');
console.log(formik.errors, 'Error');
return ( return (
<div className={'expense-form'}> <div className={'expense-form'}>
<form onSubmit={formik.handleSubmit}> <form onSubmit={formik.handleSubmit}>

View File

@@ -22,12 +22,14 @@ import {
} from 'components'; } from 'components';
import withCurrencies from 'containers/Currencies/withCurrencies'; import withCurrencies from 'containers/Currencies/withCurrencies';
import withAccounts from 'containers/Accounts/withAccounts'; import withAccounts from 'containers/Accounts/withAccounts';
import withCustomers from 'containers/Customers/withCustomers';
function ExpenseFormHeader({ function ExpenseFormHeader({
formik: { errors, touched, setFieldValue, getFieldProps, values }, formik: { errors, touched, setFieldValue, getFieldProps, values },
currenciesList, currenciesList,
accountsList, accountsList,
accountsTypes, accountsTypes,
customersItems,
}) { }) {
const [selectedItems, setSelectedItems] = useState({}); const [selectedItems, setSelectedItems] = useState({});
@@ -84,10 +86,46 @@ function ExpenseFormHeader({
// Filter payment accounts. // Filter payment accounts.
const paymentAccounts = useMemo( const paymentAccounts = useMemo(
() => accountsList.filter(a => a?.type?.key === 'current_asset'), () => accountsList.filter((a) => a?.type?.key === 'current_asset'),
[accountsList], [accountsList],
); );
const CustomerRenderer = useCallback(
(cutomer, { handleClick }) => (
<MenuItem
key={cutomer.id}
text={cutomer.display_name}
onClick={handleClick}
/>
),
[],
);
// Filter Customer
const filterCustomer = (query, customer, _index, exactMatch) => {
const normalizedTitle = customer.display_name.toLowerCase();
const normalizedQuery = query.toLowerCase();
if (exactMatch) {
return normalizedTitle === normalizedQuery;
} else {
return (
`${customer.display_name} ${normalizedTitle}`.indexOf(
normalizedQuery,
) >= 0
);
}
};
// handle change customer
const onChangeCustomer = useCallback(
(filedName) => {
return (customer) => {
setFieldValue(filedName, customer.id);
};
},
[setFieldValue],
);
return ( return (
<div className={'dashboard__insider--expense-form__header'}> <div className={'dashboard__insider--expense-form__header'}>
<Row> <Row>
@@ -105,16 +143,16 @@ function ExpenseFormHeader({
} }
> >
<ListSelect <ListSelect
items={[]} items={customersItems}
noResults={<MenuItem disabled={true} text="No results." />} noResults={<MenuItem disabled={true} text="No results." />}
// itemRenderer={} itemRenderer={CustomerRenderer}
// itemPredicate={} itemPredicate={filterCustomer}
popoverProps={{ minimal: true }} popoverProps={{ minimal: true }}
// onItemSelect={} onItemSelect={onChangeCustomer('customer_id')}
selectedItem={values.beneficiary} selectedItem={values.customer_id}
// selectedItemProp={'id'} selectedItemProp={'id'}
defaultText={<T id={'select_customer'} />} defaultText={<T id={'select_customer_account'} />}
labelProp={'beneficiary'} labelProp={'display_name'}
/> />
</FormGroup> </FormGroup>
</Col> </Col>
@@ -235,4 +273,7 @@ export default compose(
withCurrencies(({ currenciesList }) => ({ withCurrencies(({ currenciesList }) => ({
currenciesList, currenciesList,
})), })),
withCustomers(({ customersItems }) => ({
customersItems,
})),
)(ExpenseFormHeader); )(ExpenseFormHeader);

View File

@@ -8,6 +8,7 @@ import DashboardInsider from 'components/Dashboard/DashboardInsider';
import withAccountsActions from 'containers/Accounts/withAccountsActions'; import withAccountsActions from 'containers/Accounts/withAccountsActions';
import withExpensesActions from 'containers/Expenses/withExpensesActions'; import withExpensesActions from 'containers/Expenses/withExpensesActions';
import withCurrenciesActions from 'containers/Currencies/withCurrenciesActions'; import withCurrenciesActions from 'containers/Currencies/withCurrenciesActions';
import withCustomersActions from 'containers/Customers/withCustomersActions';
import { compose } from 'utils'; import { compose } from 'utils';
@@ -21,6 +22,9 @@ function Expenses({
// #wihtCurrenciesActions // #wihtCurrenciesActions
requestFetchCurrencies, requestFetchCurrencies,
// #withCustomersActions
requestFetchCustomers,
}) { }) {
const history = useHistory(); const history = useHistory();
const { id } = useParams(); const { id } = useParams();
@@ -38,6 +42,12 @@ function Expenses({
const fetchCurrencies = useQuery('currencies', () => const fetchCurrencies = useQuery('currencies', () =>
requestFetchCurrencies(), requestFetchCurrencies(),
); );
// Handle fetch customers data table or list
const fetchCustomers = useQuery('customers-table', () =>
requestFetchCustomers({}),
);
const handleFormSubmit = useCallback( const handleFormSubmit = useCallback(
(payload) => { (payload) => {
payload.redirect && history.push('/expenses-list'); payload.redirect && history.push('/expenses-list');
@@ -54,7 +64,8 @@ function Expenses({
loading={ loading={
fetchExpense.isFetching || fetchExpense.isFetching ||
fetchAccounts.isFetching || fetchAccounts.isFetching ||
fetchCurrencies.isFetching fetchCurrencies.isFetching ||
fetchCustomers.isFetching
} }
name={'expense-form'} name={'expense-form'}
> >
@@ -71,4 +82,5 @@ export default compose(
withAccountsActions, withAccountsActions,
withCurrenciesActions, withCurrenciesActions,
withExpensesActions, withExpensesActions,
withCustomersActions,
)(Expenses); )(Expenses);

View File

@@ -0,0 +1,152 @@
import React, { useMemo, useCallback } from 'react';
import * as Yup from 'yup';
import { useFormik } from 'formik';
import { Row, Col } from 'react-grid-system';
import { FormattedMessage as T, useIntl } from 'react-intl';
import { ErrorMessage, AppToaster } from 'components';
import {
Button,
Classes,
FormGroup,
InputGroup,
Intent,
Position,
} from '@blueprintjs/core';
import { compose, optionsMapToArray } from 'utils';
import withSettingsActions from 'containers/Settings/withSettingsActions';
import withSettings from 'containers/Settings/withSettings';
function ReferenceNumberForm({
onSubmit,
onClose,
initialPrefix,
initialNumber,
groupName,
requestSubmitOptions,
}) {
const { formatMessage } = useIntl();
const validationSchema = Yup.object().shape({
prefix: Yup.string(),
next_number: Yup.number(),
});
const initialValues = useMemo(
() => ({
prefix: initialPrefix || '',
next_number: initialNumber || '',
}),
[],
);
const {
errors,
values,
touched,
setFieldValue,
resetForm,
handleSubmit,
isSubmitting,
getFieldProps,
} = useFormik({
enableReinitialize: true,
initialValues: {
...initialValues,
},
validationSchema,
onSubmit: (values, { setSubmitting, setErrors }) => {
const options = optionsMapToArray(values).map((option) => {
return { key: option.key, ...option, group: groupName };
});
onSubmit(
requestSubmitOptions({ options })
.then(() => {
setSubmitting(false);
})
.catch((erros) => {
setSubmitting(false);
}),
);
},
});
// Handles dialog close.
// const handleClose = useCallback(() => {
// closeDialog(dialogName);
// }, [closeDialog, dialogName]);
// Handle dialog on closed.
const onClosed = useCallback(() => {
resetForm();
}, [resetForm]);
return (
<div>
<form onSubmit={handleSubmit}>
<div className={Classes.DIALOG_BODY}>
<p className="paragraph">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce
tincidunt porta quam,
</p>
<Row>
{/* prefix */}
<Col>
<FormGroup
label={<T id={'prefix'} />}
className={'form-group--'}
intent={errors.prefix && touched.prefix && Intent.DANGER}
helperText={
<ErrorMessage name={'prefix'} {...{ errors, touched }} />
}
>
<InputGroup
intent={errors.prefix && touched.prefix && Intent.DANGER}
{...getFieldProps('prefix')}
/>
</FormGroup>
</Col>
{/* next_number */}
<Col>
<FormGroup
label={<T id={'next_number'} />}
className={'form-group--'}
intent={
errors.next_number && touched.next_number && Intent.DANGER
}
helperText={
<ErrorMessage name={'next_number'} {...{ errors, touched }} />
}
>
<InputGroup
intent={
errors.next_number && touched.next_number && Intent.DANGER
}
{...getFieldProps('next_number')}
/>
</FormGroup>
</Col>
</Row>
</div>
<div className={Classes.DIALOG_FOOTER}>
<div className={Classes.DIALOG_FOOTER_ACTIONS}>
<Button onClick={onClose}>
<T id={'cancel'} />
</Button>
<Button
intent={Intent.PRIMARY}
type="submit"
disabled={isSubmitting}
>
<T id={'submit'} />
</Button>
</div>
</div>
</form>
</div>
);
}
export default compose(withSettingsActions)(ReferenceNumberForm);

View File

@@ -215,6 +215,8 @@ export default {
'The item category has been successfully created.', 'The item category has been successfully created.',
the_item_category_has_been_successfully_edited: the_item_category_has_been_successfully_edited:
'The item category has been successfully edited.', 'The item category has been successfully edited.',
the_item_category_has_been_successfully_deleted:
'The item category has been successfully deleted',
once_delete_these_views_you_will_not_able_restore_them: once_delete_these_views_you_will_not_able_restore_them:
"Once you delete the custom view, you won't be able to restore it later. Are you sure you want to delete this view?", "Once you delete the custom view, you won't be able to restore it later. Are you sure you want to delete this view?",
the_custom_view_has_been_successfully_deleted: the_custom_view_has_been_successfully_deleted:
@@ -765,5 +767,8 @@ export default {
something_wentwrong: 'Something went wrong.', something_wentwrong: 'Something went wrong.',
new_password: 'New password', new_password: 'New password',
license_code_: 'License code', license_code_: 'License code',
legal_organization_name: 'Legal Organization Name' legal_organization_name: 'Legal Organization Name',
prefix: 'Prefix',
next_number: 'Next Number',
journal_number_settings: 'Journal Number Settings',
}; };

View File

@@ -1,159 +1,162 @@
.make-journal-entries {
.make-journal-entries{
padding-bottom: 20px; padding-bottom: 20px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
&__header{ &__header {
padding: 25px 27px 20px; padding: 25px 27px 20px;
background: #fbfbfb; background: #fbfbfb;
.bp3-form-group{ .bp3-form-group {
.bp3-label {
.bp3-label{
font-weight: 500; font-weight: 500;
font-size: 13px; font-size: 13px;
color: #444; color: #444;
} }
} }
.bp3-button:not([class*='bp3-intent-']):not(.bp3-minimal).bp3-small {
font-size: 13px;
min-height: 33px;
margin-top: 21px;
margin-left: -30px;
}
} }
&__table{ &__table {
padding: 15px 15px 0; padding: 15px 15px 0;
.bp3-form-group{ .bp3-form-group {
margin-bottom: 0; margin-bottom: 0;
} }
.table{ .table {
border: 1px dotted rgb(195, 195, 195); border: 1px dotted rgb(195, 195, 195);
border-bottom: transparent; border-bottom: transparent;
border-left: transparent; border-left: transparent;
.th, .th,
.td{ .td {
border-left: 1px dotted rgb(195, 195, 195); border-left: 1px dotted rgb(195, 195, 195);
&.index{ &.index {
text-align: center; text-align: center;
span{ span {
width: 100%; width: 100%;
font-weight: 500; font-weight: 500;
} }
} }
} }
.thead{ .thead {
.tr .th{ .tr .th {
padding: 10px 10px; padding: 10px 10px;
background-color: #F2F5FA; background-color: #f2f5fa;
font-size: 14px; font-size: 14px;
font-weight: 500; font-weight: 500;
color: #1e1c3e; color: #1e1c3e;
&.index > div{ &.index > div {
width: 100%; width: 100%;
} }
} }
} }
.tbody{ .tbody {
.tr .td{ .tr .td {
padding: 7px; padding: 7px;
border-bottom: 1px dotted rgb(195, 195, 195); border-bottom: 1px dotted rgb(195, 195, 195);
min-height: 46px; min-height: 46px;
&.index{ &.index {
background-color: #F2F5FA; background-color: #f2f5fa;
> span{ > span {
margin-top: auto; margin-top: auto;
margin-bottom: auto; margin-bottom: auto;
} }
} }
} }
.tr{ .tr {
.bp3-form-group:not(.bp3-intent-danger) .bp3-input, .bp3-form-group:not(.bp3-intent-danger) .bp3-input,
.form-group--select-list .bp3-button{ .form-group--select-list .bp3-button {
border-color: #E5E5E5; border-color: #e5e5e5;
border-radius: 3px; border-radius: 3px;
padding-left: 8px; padding-left: 8px;
padding-right: 8px; padding-right: 8px;
} }
.form-group--select-list{ .form-group--select-list {
&.bp3-intent-danger{ &.bp3-intent-danger {
.bp3-button:not(.bp3-minimal){ .bp3-button:not(.bp3-minimal) {
border-color: #db3737; border-color: #db3737;
} }
} }
} }
&:last-of-type{ &:last-of-type {
.td{ .td {
border-bottom: transparent; border-bottom: transparent;
.bp3-button, .bp3-button,
.bp3-input-group{ .bp3-input-group {
display: none; display: none;
} }
} }
} }
.td.actions{ .td.actions {
.bp3-button{ .bp3-button {
background-color: transparent; background-color: transparent;
color: #e66d6d; color: #e66d6d;
&:hover{ &:hover {
color: #c23030; color: #c23030;
} }
svg{ svg {
color: inherit; color: inherit;
} }
} }
} }
&.row--total{ &.row--total {
.account.td, .account.td,
.debit.td, .debit.td,
.credit.td{ .credit.td {
> span{ > span {
padding-top: 2px; padding-top: 2px;
} }
} }
.debit.td, .debit.td,
.credit.td{ .credit.td {
> span{ > span {
font-weight: 600; font-weight: 600;
color: #444; color: #444;
} }
} }
} }
.td{ .td {
&.note{ &.note {
.bp3-form-group{ .bp3-form-group {
width: 100%; width: 100%;
} }
} }
} }
} }
} }
.th{ .th {
color: #444; color: #444;
font-weight: 600; font-weight: 600;
border-bottom: 1px dotted #666; border-bottom: 1px dotted #666;
} }
.td{ .td {
border-bottom: 1px dotted #999; border-bottom: 1px dotted #999;
} }
.actions.td{ .actions.td {
.bp3-button{ .bp3-button {
background: transparent; background: transparent;
margin: 0; margin: 0;
} }
@@ -161,23 +164,22 @@
} }
} }
.bp3-button{ .bp3-button {
&.button--clear-lines{ &.button--clear-lines {
background-color: #FCEFEF; background-color: #fcefef;
} }
} }
.button--clear-lines, .button--clear-lines,
.button--new-line{ .button--new-line {
padding-left: 14px; padding-left: 14px;
padding-right: 14px; padding-right: 14px;
} }
.dropzone-container{ .dropzone-container {
margin-left: auto; margin-left: auto;
} }
.dropzone{ .dropzone {
width: 300px; width: 300px;
height: 75px; height: 75px;