aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/classes/item.js31
-rw-r--r--src/components/tables/invoice-item-table.js30
-rw-r--r--src/components/tables/invoice-summary.js42
-rw-r--r--src/views/invoice/new.js10
4 files changed, 65 insertions, 48 deletions
diff --git a/src/classes/item.js b/src/classes/item.js
index 639a63f..e9e692b 100644
--- a/src/classes/item.js
+++ b/src/classes/item.js
@@ -16,7 +16,16 @@
*/
import axios from "axios";
-import { Brand } from "./brand"
+import c from "currency.js";
+import { Brand } from "./brand";
+
+// TODO: load from config or something
+export const currency = value => c(value, {
+ decimal: '.',
+ seperator: ',',
+ precision: 2,
+ symbol: '₹',
+});
export class Item {
constructor() {
@@ -62,22 +71,22 @@ export const getAllItems = (ok, fail) => {
export const editItem = (item, ok, fail) => {
axios.put(`/item/${item.Id}`, item)
.then(res => ok())
- .catch(err => fail())
+ .catch(err => fail());
}
export const getDiscountValue = (item) => item.DiscountPercentage > 0
- ? ((item.UnitPrice * item.Quantity)/100) * item.DiscountPercentage : 0.00;
+ ? currency(item.UnitPrice).multiply(item.Quantity).divide(100) : currency(0.00)
export const getGSTValue = (item) => item.GSTPercentage > 0
- ? (((item.UnitPrice * item.Quantity) - getDiscountValue(item))/100) * item.GSTPercentage : 0.00;
+ ? currency(item.UnitPrice).multiply(item.Quantity).subtract(getDiscountValue).divide(100).multiply(item.GSTPercentage) : currency(0.00)
export const getAmount = (item) =>
- (item.UnitPrice * item.Quantity) - getDiscountValue(item) + getGSTValue(item)
+ currency(item.UnitPrice).multiply(item.Quantity).add(getDiscountValue(item)).add(getGSTValue(item))
export const calcSum = (items) => items.reduce((prev, current, id, arr) => ({
- GST: prev.GST + getGSTValue(current),
- Discount: prev.Discount + getDiscountValue(current),
- UnitPrice: prev.UnitPrice + current.UnitPrice,
- Amount: prev.Amount + getAmount(current),
- Quantity: prev.Quantity + current.Quantity
-}), {GST: 0, Discount: 0, UnitPrice: 0, Amount: 0, Quantity: 0});
+ GST: prev.GST.add(getGSTValue(current)),
+ Discount: prev.Discount.add(getDiscountValue(current)),
+ UnitPrice: prev.UnitPrice.add(currency(current.UnitPrice).multiply(current.Quantity)),
+ Amount: prev.Amount.add(getAmount(current)),
+ Quantity: prev.Quantity.add(current.Quantity) // stored as a currency because it can be float
+}), {GST: currency(0), Discount: currency(0), UnitPrice: currency(0), Amount: currency(0), Quantity: currency(0)});
diff --git a/src/components/tables/invoice-item-table.js b/src/components/tables/invoice-item-table.js
index fb91af3..d008ebc 100644
--- a/src/components/tables/invoice-item-table.js
+++ b/src/components/tables/invoice-item-table.js
@@ -16,7 +16,7 @@
*/
import './scss/table.scss';
-import { getDiscountValue, getGSTValue, getAmount } from './../../classes/item';
+import { getDiscountValue, getGSTValue, getAmount, currency } from './../../classes/item';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faPencil, faTrashCan } from '@fortawesome/free-solid-svg-icons'
@@ -70,17 +70,18 @@ const ItemTable = ({items, setItems, isInterstate, sum}) => {
<td className={i.Brand.Name === "" ? "empty" : ""}>{i.Brand.Name}</td>
<td>{i.Quantity}</td>
<td className={i.UnitOfMeasure === "" ? "empty" : ""}>{i.UnitOfMeasure}</td>
- <td className={i.UnitPrice > 0 ? "" : "empty"}>{i.UnitPrice}</td>
- <td className={i.DiscountPercentage > 0 ? "" : "empty"}>{getDiscountValue(i)} ({i.DiscountPercentage}%)</td>
+ <td className={i.UnitPrice > 0 ? "" : "empty"}>{currency(i.UnitPrice).format()}</td>
+ <td className={i.DiscountPercentage > 0 ? "" : "empty"}>{getDiscountValue(i).format()} ({i.DiscountPercentage}%)</td>
{isInterstate
- ? <td className={i.GSTPercentage > 0 ? "" : "empty"}>{getGSTValue(i)} ({i.GSTPercentage}%)</td>
+ ? <td className={i.GSTPercentage > 0 ? "" : "empty"}>{getGSTValue(i).format()}</td>
: <>
- <td className={i.GSTPercentage > 0 ? "" : "empty"}>{getGSTValue(i) / 2} ({i.GSTPercentage / 2}%)</td>
- <td className={i.GSTPercentage > 0 ? "" : "empty"}>{getGSTValue(i) / 2} ({i.GSTPercentage / 2}%)</td>
+ {getGSTValue(i).distribute(2).map((j, id) =>
+ <td key={`g-${id}`} className={i.GSTPercentage > 0 ? "" : "empty"}>{j.format()} ({currency(i.GSTPercentage).divide(2).value}%)</td>
+ )}
</>
}
<td className={i.HSN === "" ? "empty" : ""}>{i.HSN}</td>
- <td>{getAmount(i)}</td>
+ <td>{getAmount(i).format()}</td>
<td className={"buttons"}>
<FontAwesomeIcon icon={faPencil} onClick={() => handleEdit(i)}/>
<FontAwesomeIcon icon={faTrashCan} onClick={() => handleDelete(i)}/>
@@ -92,19 +93,20 @@ const ItemTable = ({items, setItems, isInterstate, sum}) => {
<td className={"empty"}></td>
<td className={"empty"}></td>
<td className={"empty"}></td>
- <td className={sum.Quantity > 0 ? "" : "empty"}>{sum.Quantity}</td>
+ <td className={sum.Quantity.value > 0 ? "" : "empty"}>{sum.Quantity.value}</td>
<td className={"empty"}></td>
- <td className={sum.UnitPrice > 0 ? "" : "empty"}>{sum.UnitPrice}</td>
- <td className={sum.Discount > 0 ? "" : "empty"}>{sum.Discount}</td>
+ <td className={sum.UnitPrice.value > 0 ? "" : "empty"}>{sum.UnitPrice.format()}</td>
+ <td className={sum.Discount.value > 0 ? "" : "empty"}>{sum.Discount.format()}</td>
{isInterstate
- ? <td className={sum.GST > 0 ? "" : "empty"}>{sum.GST || 0}</td>
+ ? <td className={sum.GST.value > 0 ? "" : "empty"}>{sum.GST.format()}</td>
: <>
- <td className={sum.GST > 0 ? "" : "empty"}>{sum.GST / 2 || 0}</td>
- <td className={sum.GST > 0 ? "" : "empty"}>{sum.GST / 2 || 0}</td>
+ {sum.GST.distribute(2).map((i, id) =>
+ <td key={`g-${id}`} className={i.value > 0 ? "" : "empty"}>{i.format()}</td>
+ )}
</>
}
<td className={"empty"}></td>
- <td className={sum.Amount > 0 ? "" : "empty"}>{sum.Amount}</td>
+ <td className={sum.Amount.value > 0 ? "" : "empty"}>{sum.Amount.format()}</td>
<td className={"buttons"}>
</td>
</tr>
diff --git a/src/components/tables/invoice-summary.js b/src/components/tables/invoice-summary.js
index 5899105..7018d50 100644
--- a/src/components/tables/invoice-summary.js
+++ b/src/components/tables/invoice-summary.js
@@ -15,47 +15,47 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-import './scss/table.scss';
+import { currency } from '../../classes/item';
const InvoiceSummary = ({sum}) => {
- const totalRoundedOff = Math.round(sum.Amount);
- const roundedOffDiff = sum.Amount - totalRoundedOff;
-
- const formatter = new Intl.NumberFormat("en-US", {
- maximumSignificantDigits: 2,
- })
+ const totalRoundedOff = currency(sum.Amount !== undefined ? Math.round(sum.Amount.value) : 0.00);
+ const roundedOffDiff = sum.Amount !== undefined ? sum.Amount.subtract(totalRoundedOff) : currency(0.00);
return (
<>
<h1>Summary:</h1>
<table>
<tbody>
- <tr>
- <td>Base Total</td>
- <td>{formatter.format(sum.UnitPrice)}</td>
- </tr>
- {sum.Discount > 0 &&
+ {sum.UnitPrice !== undefined &&
+ <tr>
+ <td>Base Total</td>
+ <td>{sum.UnitPrice.format()}</td>
+ </tr>
+ }
+ {sum.Discount !== undefined && sum.Discount.value > 0 &&
<tr>
<td>Total After Discount</td>
- <td>{formatter.format(sum.UnitPrice - sum.Discount)} (-{formatter.format(sum.Discount)})</td>
+ <td>{sum.UnitPrice.subtract(sum.Discount).format()} (-{sum.Discount.format()})</td>
</tr>
}
- {sum.GST > 0 &&
+ {sum.GST !== undefined && sum.GST.value > 0 &&
<tr>
<td>Total After Tax</td>
- <td>{formatter.format(sum.UnitPrice - (sum.Discount > 0 ? sum.Discount : 0) + sum.GST)} (+{formatter.format(sum.GST)})</td>
+ <td>{sum.UnitPrice.subtract(sum.Discount.value > 0 ? sum.Discount : currency(0)).add(sum.GST).format()} (+{sum.GST.format()})</td>
</tr>
}
- {(isNaN(roundedOffDiff) || roundedOffDiff !== 0) &&
+ {roundedOffDiff.intValue !== 0 &&
<tr>
<td>Rounded Off</td>
- <td>{`${roundedOffDiff > 0 ? `(-) ${formatter.format(roundedOffDiff)}` : `(+) ${formatter.format(roundedOffDiff * -1)}`}`}</td>
+ <td>{`${roundedOffDiff.value > 0 ? `(-) ${roundedOffDiff.format()}` : `(+) ${roundedOffDiff.multiply(-1).format()}`}`}</td>
+ </tr>
+ }
+ {sum.Amount !== undefined &&
+ <tr>
+ <td>Grand Total</td>
+ <td>{sum.Amount.subtract(roundedOffDiff).format()}</td>
</tr>
}
- <tr>
- <td>Grand Total</td>
- <td>{formatter.format(sum.Amount - (isNaN(roundedOffDiff) ? 0 : roundedOffDiff))}</td>
- </tr>
</tbody>
</table>
</>
diff --git a/src/views/invoice/new.js b/src/views/invoice/new.js
index 429808f..be180cf 100644
--- a/src/views/invoice/new.js
+++ b/src/views/invoice/new.js
@@ -21,7 +21,7 @@ import ItemTable from '../../components/tables/invoice-item-table';
import InvoiceSummary from '../../components/tables/invoice-summary';
import { InvoiceClient } from '../../classes/client';
-import { calcSum } from '../../classes/item';
+import { calcSum, currency } from '../../classes/item';
import { useState, useEffect } from 'react';
@@ -31,7 +31,13 @@ const NewInvoicePage = () => {
const [items, setItems] = useState([]);
//const [isInterstate, setIsInterstate] = useState(false);
const isInterstate = false; // temporary
- const [sum, setSum] = useState({});
+ const [sum, setSum] = useState({
+ GST: currency(0),
+ Discount: currency(0),
+ UnitPrice: currency(0),
+ Amount: currency(0),
+ Quantity: currency(0)
+ });
useEffect(() => setShippingAddressId(-1), [client]);