diff --git a/backend/apps/journals/migrations/0005_auto_20210331_1613.py b/backend/apps/journals/migrations/0005_auto_20210331_1613.py new file mode 100644 index 0000000..914f6ae --- /dev/null +++ b/backend/apps/journals/migrations/0005_auto_20210331_1613.py @@ -0,0 +1,23 @@ +# Generated by Django 3.1.6 on 2021-03-31 20:13 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('journals', '0004_journal_user'), + ] + + operations = [ + migrations.AddField( + model_name='journal', + name='comment', + field=models.CharField(max_length=255, null=True, verbose_name='comment'), + ), + migrations.AlterField( + model_name='journal', + name='user', + field=models.IntegerField(null=True, verbose_name='user'), + ), + ] diff --git a/backend/apps/journals/models.py b/backend/apps/journals/models.py index 7600572..a39eee0 100644 --- a/backend/apps/journals/models.py +++ b/backend/apps/journals/models.py @@ -4,12 +4,13 @@ class Journal(models.Model): status = models.IntegerField(verbose_name='status', default=True) coa = models.IntegerField(verbose_name='coa', null=True) - user = models.IntegerField(verbose_name='coa', null=True) + user = models.IntegerField(verbose_name='user', null=True) debit = models.FloatField(verbose_name="debit", default=0.00, null=True) credit = models.FloatField(verbose_name="credit", default=0.00, null=True) amount = models.FloatField(verbose_name="amount", default=0.00, null=True) date = models.DateField(verbose_name='date', auto_now_add=True, null=True) source = models.CharField(verbose_name='source', max_length=255, null=True) + comment = models.CharField(verbose_name='comment', max_length=255, null=True) def __str__(self): return self.name diff --git a/frontend/src/components/JournalModal.js b/frontend/src/components/JournalModal.js new file mode 100644 index 0000000..f2a2bdc --- /dev/null +++ b/frontend/src/components/JournalModal.js @@ -0,0 +1,146 @@ +import React, { Component } from "react"; +import { + Button, + Modal, + ModalHeader, + ModalBody, + ModalFooter, + Form, + FormGroup, + Input, + Label, +} from "reactstrap"; +import { Header, Table, Checkbox, Dropdown } from 'semantic-ui-react' +import API from '../api' + + +export default class JournalModal extends Component { + constructor(props) { + super(props); + this.state = { + activeItem: this.props.activeItem, + isAdd: this.props.isAdd, + coas: this.props.coas + } + } + + isAddModal = () => { + if (this.state.isAdd) { + return ( + New Journal Entry + ) + } + return ( + Edit Journal Entry + ) + } + + handleChange = (e) => { + let { name, value } = e.target; + + if (e.target.type === "checkbox") { + value = e.target.checked; + } + + const activeItem = { ...this.state.activeItem, [name]: value }; + this.setState({ activeItem }); + }; + + render() { + const { onSave } = this.props; + + return ( + + {this.isAddModal()} + +
+ + + + + + + + + + + + {this.state.coas.map(coa => ())} + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ ) + } +} \ No newline at end of file diff --git a/frontend/src/components/JournalTable.js b/frontend/src/components/JournalTable.js index 73dbd4f..605ad82 100644 --- a/frontend/src/components/JournalTable.js +++ b/frontend/src/components/JournalTable.js @@ -1,26 +1,49 @@ import React, { useState, useEffect } from 'react' import API from '../api' -import { Header, Table, Button, Checkbox, Input } from 'semantic-ui-react' +import { Header, Table, Button, Checkbox, Dropdown } from 'semantic-ui-react' +import JouralModal from '../components/JournalModal' +import JournalModal from '../components/JournalModal'; export default function LogTable() { const [journalList, setJournalList] = useState(null); const [selectedJournals, setSelectedJournals] = useState([]); + const [tableRows, setTableRows] = useState(); const [coaList, setCoaList] = useState(null); + const [activeItem, setActiveItem] = useState({ + status: 2, + coa: 1, + user: "", + debit: 0.00, + credit: 0.00, + amount: 0.00, + source: "", + comment: "", + }); + const [modal, setModal] = useState(false); + const [toggle, setToggle] = useState(true); + const [isAdd, setIsAdd] = useState(false); + useEffect(async () => { const journals = await API.get('/api/journals/admin/').then(res => res.data); const coas = await API.get('/api/coa/admin/').then(res => res.data); setCoaList(coas); setJournalList(journals); - }, [setJournalList, setCoaList]); + setTableRows(renderTableRows(journals, coas)); + }, [setTableRows, setJournalList, setCoaList]); const getCoaInfo = (coas, coaID) => { return coas.filter(coa => coa["id"] == coaID)[0]["name"] } const refreshItems = async () => { - const journals = await API.get('/api/journals/admin/').then(res => res.data); - setJournalList(journals); + let i = 2; + while (i != 0) { + const journals = await API.get('/api/journals/admin/').then(res => res.data); + const coas = await API.get('/api/coa/admin/').then(res => res.data); + setTableRows(renderTableRows(journals, coas)); + i--; + } } const handleRowsSelected = (eve, e, item) => { @@ -30,15 +53,111 @@ export default function LogTable() { setSelectedJournals(selectedJournals.filter((el) => el.id != item.id)) } - const deleteSelectedRows = () => { - for (let journal in selectedJournals) { - API.delete(`/api/journals/admin/${selectedJournals[journal].id}/`).then(res => res.data); + const verifyIsCheked = (journalList, item) => { + let arr = journalList.filter((el) => el.id == item.id); + if (arr.length == 0) + return false; + else + return true; + } + + const handleSubmit = async (item) => { + setModal(!modal) + setIsAdd(true); + + if (selectedJournals != null || selectedJournals[0] != undefined) { + handleEditAccount(item) } + + API.post(`/api/journals/admin/`, item).then(res => res.data); + refreshItems(); setSelectedJournals([]); - renderTableRows(journalList, coaList) - window.location.replace('/apps/journals'); } + const handleEditAccount = (item) => { + setIsAdd(false); + setActiveItem(selectedJournals[0]) + } + + const deleteSelectedRows = async (journals) => { + for (let entry in journals) { + API.delete(`/api/journals/admin/${journals[entry].id}/`).then(res => res.data); + } + refreshItems(); + } + + const handleChange = async (e, item) => { + item.status = Number.parseInt(e.value) + await API.put(`/api/journals/admin/${item.id}/`, item).then(res => res.data); + refreshItems(); + } + + const mapValueToStatus = (value) => { + switch (value) { + case "Approved": + return 1 + case "Pending": + return 2 + case "Rejected": + return 3 + default: + return "Unknown" + } + } + + const mapStatusToValue = (status) => { + switch(Number.parseInt(status)) { + case 1: + return "Approved" + case 2: + return "Pending" + case 3: + return "Rejected" + default: + return "Unknown" + } + } + + const handleAddItem = () => { + setActiveItem({ + status: 1, + coa: 1, + user: 1, + debit: 0.00, + credit: 0.00, + amount: 0.00, + source: "", + comment: "", + }); + toggleModal(true); + setIsAdd(true); + } + + const toggleModal = (state) => { + setModal(state) + } + + const statusOptions = [ + { + key: 'Approved', + text: 'Approved', + value: '1', + icon: 'check', + }, + { + key: 'Pending', + text: 'Pending', + value: '2', + icon: 'history', + }, + { + key: 'Rejected', + text: 'Rejected', + value: '3', + icon: 'stop circle outline', + }, + ] + const renderTableRows = (list, coas) => { if (list == null) { @@ -47,13 +166,19 @@ export default function LogTable() { return ( - handleRowsSelected(eve, e, log)} /> + handleRowsSelected(eve, e, log)} />
{log["date"]}
-
{log["status"]}
+ handleChange(e, log)} + />
{getCoaInfo(coas, log["coa"])}
@@ -70,6 +195,9 @@ export default function LogTable() {
{(log["source"] != null ? log["source"] : "Unknown")}
+ +
{(log["comment"] != null ? log["comment"] : "N/A")}
+
) }); @@ -79,9 +207,9 @@ export default function LogTable() { return (
- - - + + +
@@ -94,12 +222,21 @@ export default function LogTable() { Credit Amount Source + Comment - {renderTableRows(journalList, coaList)} + {tableRows}
-
+ { modal ? ( + + ) : null} + ) } diff --git a/frontend/src/components/TitleBar.js b/frontend/src/components/TitleBar.js index ddb035e..f890aef 100644 --- a/frontend/src/components/TitleBar.js +++ b/frontend/src/components/TitleBar.js @@ -1,5 +1,5 @@ import React, { useEffect, useState } from 'react' -import { Container, Divider, Button } from 'semantic-ui-react'; +import { Container, Divider, Button, Icon } from 'semantic-ui-react'; import '../css/components/TitleBar.css' export default function TitleBar(props) { @@ -13,6 +13,7 @@ export default function TitleBar(props) {

{header}

+