mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-17 13:20:31 +00:00
feat: allow quantity of entries accept decimal value (#753)
This commit is contained in:
@@ -121,7 +121,7 @@ export default class BillsController extends BaseController {
|
||||
check('entries.*.index').exists().isNumeric().toInt(),
|
||||
check('entries.*.item_id').exists().isNumeric().toInt(),
|
||||
check('entries.*.rate').exists().isNumeric().toFloat(),
|
||||
check('entries.*.quantity').exists().isNumeric().toInt(),
|
||||
check('entries.*.quantity').exists().isNumeric().toFloat(),
|
||||
check('entries.*.discount')
|
||||
.optional({ nullable: true })
|
||||
.isNumeric()
|
||||
|
||||
@@ -170,7 +170,7 @@ export default class VendorCreditController extends BaseController {
|
||||
check('entries.*.index').exists().isNumeric().toInt(),
|
||||
check('entries.*.item_id').exists().isNumeric().toInt(),
|
||||
check('entries.*.rate').exists().isNumeric().toFloat(),
|
||||
check('entries.*.quantity').exists().isNumeric().toInt(),
|
||||
check('entries.*.quantity').exists().isNumeric().toFloat(),
|
||||
check('entries.*.discount')
|
||||
.optional({ nullable: true })
|
||||
.isNumeric()
|
||||
@@ -209,7 +209,7 @@ export default class VendorCreditController extends BaseController {
|
||||
check('entries.*.index').exists().isNumeric().toInt(),
|
||||
check('entries.*.item_id').exists().isNumeric().toInt(),
|
||||
check('entries.*.rate').exists().isNumeric().toFloat(),
|
||||
check('entries.*.quantity').exists().isNumeric().toInt(),
|
||||
check('entries.*.quantity').exists().isNumeric().toFloat(),
|
||||
check('entries.*.discount')
|
||||
.optional({ nullable: true })
|
||||
.isNumeric()
|
||||
|
||||
@@ -233,7 +233,7 @@ export default class PaymentReceivesController extends BaseController {
|
||||
check('entries.*.index').exists().isNumeric().toInt(),
|
||||
check('entries.*.item_id').exists().isNumeric().toInt(),
|
||||
check('entries.*.rate').exists().isNumeric().toFloat(),
|
||||
check('entries.*.quantity').exists().isNumeric().toInt(),
|
||||
check('entries.*.quantity').exists().isNumeric().toFloat(),
|
||||
check('entries.*.discount')
|
||||
.optional({ nullable: true })
|
||||
.isNumeric()
|
||||
@@ -755,9 +755,8 @@ export default class PaymentReceivesController extends BaseController {
|
||||
const { tenantId } = req;
|
||||
|
||||
try {
|
||||
const data = await this.getCreditNoteStateService.getCreditNoteState(
|
||||
tenantId
|
||||
);
|
||||
const data =
|
||||
await this.getCreditNoteStateService.getCreditNoteState(tenantId);
|
||||
return res.status(200).send({ data });
|
||||
} catch (error) {
|
||||
next(error);
|
||||
|
||||
@@ -172,7 +172,7 @@ export default class SalesEstimatesController extends BaseController {
|
||||
check('entries').exists().isArray({ min: 1 }),
|
||||
check('entries.*.index').exists().isNumeric().toInt(),
|
||||
check('entries.*.item_id').exists().isNumeric().toInt(),
|
||||
check('entries.*.quantity').exists().isNumeric().toInt(),
|
||||
check('entries.*.quantity').exists().isNumeric().toFloat(),
|
||||
check('entries.*.rate').exists().isNumeric().toFloat(),
|
||||
check('entries.*.description').optional({ nullable: true }).trim(),
|
||||
check('entries.*.discount')
|
||||
@@ -562,9 +562,8 @@ export default class SalesEstimatesController extends BaseController {
|
||||
const { tenantId } = req;
|
||||
|
||||
try {
|
||||
const data = await this.saleEstimatesApplication.getSaleEstimateState(
|
||||
tenantId
|
||||
);
|
||||
const data =
|
||||
await this.saleEstimatesApplication.getSaleEstimateState(tenantId);
|
||||
return res.status(200).send({ data });
|
||||
} catch (error) {
|
||||
next(error);
|
||||
|
||||
@@ -148,7 +148,7 @@ export default class SalesReceiptsController extends BaseController {
|
||||
check('entries.*.id').optional({ nullable: true }).isNumeric().toInt(),
|
||||
check('entries.*.index').exists().isNumeric().toInt(),
|
||||
check('entries.*.item_id').exists().isNumeric().toInt(),
|
||||
check('entries.*.quantity').exists().isNumeric().toInt(),
|
||||
check('entries.*.quantity').exists().isNumeric().toFloat(),
|
||||
check('entries.*.rate').exists().isNumeric().toFloat(),
|
||||
check('entries.*.discount')
|
||||
.optional({ nullable: true })
|
||||
@@ -392,9 +392,8 @@ export default class SalesReceiptsController extends BaseController {
|
||||
|
||||
// Retrieves receipt in pdf format.
|
||||
try {
|
||||
const data = await this.saleReceiptsApplication.getSaleReceiptState(
|
||||
tenantId
|
||||
);
|
||||
const data =
|
||||
await this.saleReceiptsApplication.getSaleReceiptState(tenantId);
|
||||
return res.status(200).send({ data });
|
||||
} catch (error) {
|
||||
next(error);
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* @param { import("knex").Knex } knex
|
||||
* @returns { Promise<void> }
|
||||
*/
|
||||
exports.up = function (knex) {
|
||||
return knex.schema
|
||||
.table('items_entries', (table) => {
|
||||
table.decimal('quantity', 13, 3).alter();
|
||||
})
|
||||
.table('inventory_transactions', (table) => {
|
||||
table.decimal('quantity', 13, 3).alter();
|
||||
})
|
||||
.table('inventory_cost_lot_tracker', (table) => {
|
||||
table.decimal('quantity', 13, 3).alter();
|
||||
})
|
||||
.table('items', (table) => {
|
||||
table.decimal('quantityOnHand', 13, 3).alter();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param { import("knex").Knex } knex
|
||||
* @returns { Promise<void> }
|
||||
*/
|
||||
exports.down = function (knex) {
|
||||
return knex.schema
|
||||
.table('items_entries', (table) => {
|
||||
table.integer('quantity').alter();
|
||||
})
|
||||
.table('inventory_transactions', (table) => {
|
||||
table.integer('quantity').alter();
|
||||
})
|
||||
.table('inventory_cost_lot_tracker', (table) => {
|
||||
table.integer('quantity').alter();
|
||||
})
|
||||
.table('items', (table) => {
|
||||
table.integer('quantityOnHand').alter();
|
||||
});
|
||||
};
|
||||
@@ -1,8 +1,6 @@
|
||||
// @ts-nocheck
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { FormGroup, NumericInput, Intent } from '@blueprintjs/core';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { CellType } from '@/constants';
|
||||
import { CLASSES } from '@/constants/classes';
|
||||
|
||||
@@ -12,37 +10,44 @@ import { CLASSES } from '@/constants/classes';
|
||||
export default function NumericInputCell({
|
||||
row: { index },
|
||||
column: { id },
|
||||
cell: { value: initialValue },
|
||||
cell: { value: controlledInputValue },
|
||||
payload,
|
||||
}) {
|
||||
const [value, setValue] = useState(initialValue);
|
||||
}: any) {
|
||||
const [valueAsNumber, setValueAsNumber] = useState<number | null>(
|
||||
controlledInputValue || null,
|
||||
);
|
||||
const handleInputValueChange = (
|
||||
valueAsNumber: number,
|
||||
valueAsString: string,
|
||||
) => {
|
||||
setValueAsNumber(valueAsNumber);
|
||||
};
|
||||
const handleInputBlur = () => {
|
||||
payload.updateData(index, id, valueAsNumber);
|
||||
};
|
||||
|
||||
const handleValueChange = (newValue) => {
|
||||
setValue(newValue);
|
||||
};
|
||||
const onBlur = () => {
|
||||
payload.updateData(index, id, value);
|
||||
};
|
||||
useEffect(() => {
|
||||
setValue(initialValue);
|
||||
}, [initialValue]);
|
||||
setValueAsNumber(controlledInputValue);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [controlledInputValue]);
|
||||
|
||||
const error = payload.errors?.[index]?.[id];
|
||||
|
||||
return (
|
||||
<FormGroup
|
||||
intent={error ? Intent.DANGER : null}
|
||||
intent={error ? Intent.DANGER : undefined}
|
||||
className={classNames(CLASSES.FILL)}
|
||||
>
|
||||
<NumericInput
|
||||
value={value}
|
||||
onValueChange={handleValueChange}
|
||||
onBlur={onBlur}
|
||||
fill={true}
|
||||
asyncControl
|
||||
value={controlledInputValue}
|
||||
onValueChange={handleInputValueChange}
|
||||
onBlur={handleInputBlur}
|
||||
buttonPosition={'none'}
|
||||
fill
|
||||
/>
|
||||
</FormGroup>
|
||||
);
|
||||
}
|
||||
|
||||
NumericInputCell.cellType = CellType.Field;
|
||||
NumericInputCell.cellType = CellType.Field;
|
||||
|
||||
@@ -13,7 +13,6 @@ import {
|
||||
Tag,
|
||||
} from '@blueprintjs/core';
|
||||
import {
|
||||
FormatNumberCell,
|
||||
TextOverviewTooltipCell,
|
||||
FormattedMessage as T,
|
||||
Choose,
|
||||
@@ -51,9 +50,8 @@ export const useBillReadonlyEntriesTableColumns = () => {
|
||||
},
|
||||
{
|
||||
Header: intl.get('quantity'),
|
||||
accessor: 'quantity',
|
||||
Cell: FormatNumberCell,
|
||||
width: getColumnWidth(entries, 'quantity', {
|
||||
accessor: 'quantity_formatted',
|
||||
width: getColumnWidth(entries, 'quantity_formatted', {
|
||||
minWidth: 60,
|
||||
magicSpacing: 5,
|
||||
}),
|
||||
|
||||
@@ -48,9 +48,8 @@ export const useCreditNoteReadOnlyEntriesColumns = () => {
|
||||
},
|
||||
{
|
||||
Header: intl.get('quantity'),
|
||||
accessor: 'quantity',
|
||||
Cell: FormatNumberCell,
|
||||
width: getColumnWidth(entries, 'quantity', {
|
||||
accessor: 'quantity_formatted',
|
||||
width: getColumnWidth(entries, 'quantity_formatted', {
|
||||
minWidth: 60,
|
||||
magicSpacing: 5,
|
||||
}),
|
||||
|
||||
@@ -54,11 +54,10 @@ export const useInvoiceReadonlyEntriesColumns = () => {
|
||||
{
|
||||
Header: intl.get('quantity'),
|
||||
accessor: 'quantity',
|
||||
Cell: FormatNumberCell,
|
||||
align: 'right',
|
||||
disableSortBy: true,
|
||||
textOverview: true,
|
||||
width: getColumnWidth(entries, 'quantity', {
|
||||
width: getColumnWidth(entries, 'quantity_formatted', {
|
||||
minWidth: 60,
|
||||
magicSpacing: 5,
|
||||
}),
|
||||
|
||||
@@ -72,7 +72,7 @@ export const useEstimateTransactionsColumns = () => {
|
||||
{
|
||||
id: 'qunatity',
|
||||
Header: intl.get('item.drawer_quantity_sold'),
|
||||
accessor: 'quantity',
|
||||
accessor: 'quantity_formatted',
|
||||
align: 'right',
|
||||
width: 100,
|
||||
},
|
||||
|
||||
@@ -31,9 +31,8 @@ export const useReceiptReadonlyEntriesTableColumns = () => {
|
||||
},
|
||||
{
|
||||
Header: intl.get('quantity'),
|
||||
accessor: 'quantity',
|
||||
Cell: FormatNumberCell,
|
||||
width: getColumnWidth(entries, 'quantity', {
|
||||
accessor: 'quantity_formatted',
|
||||
width: getColumnWidth(entries, 'quantity_formatted', {
|
||||
minWidth: 60,
|
||||
magicSpacing: 5,
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user