Skip to content

Commit 3f49de9

Browse files
Saska KolehmainenSaska Kolehmainen
Saska Kolehmainen
authored and
Saska Kolehmainen
committed
Added the ability to apply discounts to the invoice.
1 parent 592ca42 commit 3f49de9

File tree

2 files changed

+94
-6
lines changed

2 files changed

+94
-6
lines changed

src/pages/invoices/$id/_layout.js

+78-6
Original file line numberDiff line numberDiff line change
@@ -28,25 +28,45 @@ import LineItems from '../../../components/invoices/line-items';
2828
import FooterToolbar from '../../../components/layout/footer-toolbar';
2929
import { OrganizationContext } from '../../../providers/contexts';
3030

31+
let discountValue;
32+
let discountType;
33+
3134
const totals = (lineItems, taxRates) => {
3235
let subTotal = currency(0, { separator: '', symbol: '' });
3336
let taxTotal = currency(0, { separator: '', symbol: '' });
37+
let discount = currency(0, { separator: '', symbol: '' });
38+
3439

3540
forEach(lineItems, line => {
3641
if (has(line, 'subtotal')) {
3742
subTotal = subTotal.add(line.subtotal);
43+
44+
let lineDiscount;
45+
if(discountValue !== 0 | discountValue !== ""){
46+
if(discountType === "%"){
47+
lineDiscount = currency(line.subtotal).multiply(discountValue / 100);
48+
} else if(discountType==="currency"){
49+
lineDiscount = currency(lineDiscount).add(discountValue / lineItems.length);
50+
}
51+
}
3852
if (has(line, 'taxRate')) {
39-
const taxRate = get(taxRates.items, line.taxRate);
53+
const taxRate = get(taxRates.items, line.taxRate)
54+
4055
if (taxRate) {
41-
const lineTax = currency(line.subtotal).multiply(taxRate.percentage / 100);
56+
const afterDiscount = currency(line.subtotal).subtract(lineDiscount)
57+
const lineTax = afterDiscount.multiply(taxRate.percentage / 100);
4258
taxTotal = taxTotal.add(lineTax);
4359
}
4460
}
61+
62+
discount = discount.add(lineDiscount)
4563
}
4664
});
4765

48-
const total = subTotal.add(taxTotal);
49-
return { subTotal, taxTotal, total };
66+
67+
const total = currency(subTotal, { separator: '', symbol: '' }).subtract(discount).add(taxTotal);
68+
return { subTotal, taxTotal, total, discount};
69+
5070
};
5171

5272
class InvoiceForm extends Component {
@@ -83,6 +103,16 @@ class InvoiceForm extends Component {
83103
}
84104
};
85105

106+
onDiscountTypeChange = (value) => {
107+
discountType = value
108+
}
109+
110+
onDiscountChange = (value) => {
111+
if (value !== "" | value !== 0) {
112+
discountValue = value
113+
}
114+
};
115+
86116
onStateSelect = (_id, _rev, key) => {
87117
this.props.dispatch({
88118
type: 'invoices/state',
@@ -132,7 +162,7 @@ class InvoiceForm extends Component {
132162
handleSubmit,
133163
submitting,
134164
} = this.props;
135-
const { subTotal, taxTotal, total } = totals(lineItems, taxRates);
165+
const { subTotal, taxTotal, total, discount } = totals(lineItems, taxRates);
136166
const invoice = get(invoices.items, get(this.props, ['match', 'params', 'id']));
137167

138168
const stateMenu = (_id, _rev) => (
@@ -261,6 +291,24 @@ class InvoiceForm extends Component {
261291
</Col>
262292
</Row>
263293

294+
<Row gutter={16}>
295+
<Col span={5} style={{ marginTop: '20px' }}>
296+
<Field
297+
name="discountValue"
298+
component={AInput}
299+
label={<Trans>Discount</Trans>}
300+
onChange={(event, newValue) =>
301+
this.onDiscountChange(newValue)
302+
}
303+
/>
304+
</Col>
305+
<Col span={3} style={{ marginTop: '20px'}}>
306+
<Field name="discountType" component={ASelect} onDrop={e => e.preventDefault()} label=" " defaultValue="%" onChange={(value) => this.onDiscountTypeChange(value)}>
307+
<Select.Option value="%">%</Select.Option>
308+
<Select.Option value="currency">{currency}</Select.Option>
309+
</Field>
310+
</Col>
311+
</Row>
264312
<Row gutter={16}>
265313
<Col span={8} style={{ marginTop: '20px' }}>
266314
<Field
@@ -299,6 +347,26 @@ class InvoiceForm extends Component {
299347
</h4>
300348
</td>
301349
</tr>
350+
{ discount > 0 && <tr>
351+
<td style={{ textAlign: 'right' }}>
352+
<Trans>Discount</Trans>
353+
</td>
354+
<td style={{ textAlign: 'right' }}>
355+
<NumberFormat
356+
value={discount}
357+
format={{
358+
style: 'currency',
359+
currency:
360+
currency || get(context.state, 'organization.currency', 'EUR'),
361+
minimumFractionDigits: get(
362+
context.state,
363+
'organization.minimum_fraction_digits',
364+
2
365+
),
366+
}}
367+
/>
368+
</td>
369+
</tr>}
302370
<tr>
303371
<td style={{ textAlign: 'right' }}>
304372
<Trans>Tax</Trans>
@@ -432,18 +500,22 @@ export default withI18n()(
432500
''
433501
),
434502
lineItems: [{}],
503+
discountValue: selector(state, 'discountValue'),
504+
discountType: selector(state, 'discountType'),
505+
discount: selector(state, 'discount'),
435506
},
436507
}))(
437508
reduxForm({
438509
form: 'invoice',
439510
onSubmit: async (data, dispatch, props) => {
440511
const { lineItems, taxRates } = props;
441-
const { subTotal, taxTotal, total } = totals(lineItems, taxRates);
512+
const { subTotal, taxTotal, total, discount } = totals(lineItems, taxRates);
442513
return await dispatch({
443514
type: 'invoices/save',
444515
data: {
445516
...data,
446517
subTotal: subTotal.format(),
518+
discount: discount.format(),
447519
taxTotal: taxTotal.format(),
448520
total: total.format(),
449521
},

src/pages/invoices/$id/pdf.js

+16
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,22 @@ class Invoice extends Component {
239239
/>
240240
</td>
241241
</tr>
242+
{ invoice.discount > 0 && <tr>
243+
<td colSpan="2" className="border-top-0" />
244+
<td colSpan="2" className="border-top-0">
245+
<Trans>Discount</Trans>
246+
</td>
247+
<td className="text-right border-top-0">
248+
<NumberFormat
249+
value={invoice.discount}
250+
format={{
251+
style: 'currency',
252+
currency: invoice.currency,
253+
minimumFractionDigits: get(organization, 'minimum_fraction_digits', 2),
254+
}}
255+
/>
256+
</td>
257+
</tr>}
242258
<tr>
243259
<td colSpan="2" className="border-top-0" />
244260
<td colSpan="2" className="border-top-0">

0 commit comments

Comments
 (0)