Skip to content

Commit

Permalink
Clinical SOW Display
Browse files Browse the repository at this point in the history
  • Loading branch information
Harin329 committed Jul 28, 2023
1 parent c01a1d1 commit b8ae928
Show file tree
Hide file tree
Showing 24 changed files with 395 additions and 285 deletions.
1 change: 1 addition & 0 deletions backend/src/controllers/billingController.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export default class BillingController {
billable_id: req.body.billable_id,
sow_id: req.body.sow_id,
project_id: req.body.project_id,
answer_id: req.body.answer_id,
name: req.body.name,
quantity: req.body.quantity,
cost: req.body.cost,
Expand Down
3 changes: 2 additions & 1 deletion backend/src/models/billable.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,12 @@ export class Billable {

saveBillable(billable, result) {
con.query(
"CALL save_billable(?,?,?,?,?,?,?,?,?,?,?,?)",
"CALL save_billable(?,?,?,?,?,?,?,?,?,?,?,?,?)",
[
billable.billable_id,
billable.sow_id,
billable.project_id,
billable.answer_id,
billable.name,
billable.quantity,
billable.cost,
Expand Down
1 change: 1 addition & 0 deletions database/init/billable.sql
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ CREATE TABLE `billable` (
`billable_id` VARCHAR(50) NOT NULL,
`task_uuid` VARCHAR(50) NOT NULL,
`fk_project_id` VARCHAR(50) NOT NULL,
`answer_id` VARCHAR(50),
`name` VARCHAR(50),
`quantity` DOUBLE,
`cost` DOUBLE,
Expand Down
19 changes: 15 additions & 4 deletions database/procedures/billableProc.sql
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ CREATE PROCEDURE `save_billable` (
IN `_billable_id` VARCHAR(50),
IN `_task_uuid` VARCHAR(50),
IN `_fk_project_id` VARCHAR(50),
IN `_answer_id` VARCHAR(50),
IN `_name` VARCHAR(50),
IN `_quantity` DOUBLE,
IN `_cost` DOUBLE,
Expand All @@ -27,6 +28,7 @@ INSERT INTO `billable` (
`billable_id`,
`task_uuid`,
`fk_project_id`,
`answer_id`,
`name`,
`quantity`,
`cost`,
Expand All @@ -42,6 +44,7 @@ VALUES
`_billable_id`,
`_task_uuid`,
`_fk_project_id`,
`_answer_id`,
`_name`,
`_quantity`,
`_cost`,
Expand All @@ -55,6 +58,7 @@ VALUES
billable.billable_id=_billable_id,
billable.task_uuid=_task_uuid,
billable.fk_project_id=_fk_project_id,
billable.answer_id=_answer_id,
billable.name=_name,
billable.quantity=_quantity,
billable.cost=_cost,
Expand All @@ -76,15 +80,18 @@ END $$
CREATE PROCEDURE `load_billable` ()

BEGIN
SELECT billable.*, u.username, o.organization_name, p.project_name, t.task_id, st.fk_task_id, st.subtask_id, t.task_state, st.subtask_state FROM billable
SELECT billable.*, u.username, o.organization_name, p.project_name, c.sample_id, c.authorized_by, t.task_id, st.fk_task_id, st.subtask_id, t.task_state, st.subtask_state FROM billable
LEFT JOIN tasks t on t.task_uuid = billable.task_uuid
LEFT JOIN subtasks st on st.subtask_uuid = billable.task_uuid
LEFT JOIN users u on u.user_id = billable.created_by
LEFT JOIN organizations o on o.organization_id = u.fk_organization_id
LEFT JOIN projects p on p.project_id = billable.fk_project_id
LEFT JOIN questions_answer qa on qa.answer_id = billable.answer_id
LEFT JOIN clinical c on c.fk_questions_answer_id = qa.answer_id and c.fk_survey_id = t.fk_survey_id
WHERE billable.billed = 0
AND (t.task_state != "archived" OR t.task_state IS NULL)
AND (st.subtask_state != "archived" OR st.subtask_state IS NULL);
AND (st.subtask_state != "archived" OR st.subtask_state IS NULL)
ORDER BY billable.createdDate DESC;
END $$

CREATE PROCEDURE `load_billable_with_filter` (
Expand All @@ -101,14 +108,16 @@ CREATE PROCEDURE `load_billable_with_filter` (
)

BEGIN
SELECT billable.*, u.username, o.organization_name, p.project_name, t.task_id, st.fk_task_id, st.subtask_id, t.task_state, st.subtask_state FROM billable
SELECT billable.*, u.username, o.organization_name, p.project_name, c.sample_id, c.authorized_by, t.task_id, st.fk_task_id, st.subtask_id, t.task_state, st.subtask_state FROM billable
LEFT JOIN tasks t on t.task_uuid = billable.task_uuid
LEFT JOIN subtasks st on st.subtask_uuid = billable.task_uuid
LEFT JOIN costcenter_assignments ca on ca.fk_project_id = billable.fk_project_id
LEFT JOIN project_assignments pa on pa.fk_project_id = billable.fk_project_id
LEFT JOIN users u on u.user_id = billable.created_by
LEFT JOIN organizations o on o.organization_id = u.fk_organization_id
LEFT JOIN projects p on p.project_id = billable.fk_project_id
LEFT JOIN questions_answer qa on qa.answer_id = billable.answer_id
LEFT JOIN clinical c on c.fk_questions_answer_id = qa.answer_id and c.fk_survey_id = t.fk_survey_id
WHERE (name = _service_name OR _service_name IS NULL OR _service_name = '')
AND (ca.fk_cost_center_id = _costcenter_id OR _costcenter_id IS NULL OR _costcenter_id = '')
AND (billable.fk_project_id = _project_id OR _project_id IS NULL OR _project_id = '')
Expand All @@ -126,9 +135,11 @@ CREATE PROCEDURE `load_billable_by_sow` (
)

BEGIN
SELECT billable.*, t.task_id, st.fk_task_id, st.subtask_id FROM billable
SELECT billable.*, c.sample_id, c.authorized_by, t.task_id, st.fk_task_id, st.subtask_id FROM billable
LEFT JOIN tasks t on t.task_uuid = billable.task_uuid
LEFT JOIN subtasks st on st.subtask_uuid = billable.task_uuid
LEFT JOIN questions_answer qa on qa.answer_id = billable.answer_id
LEFT JOIN clinical c on c.fk_questions_answer_id = qa.answer_id and c.fk_survey_id = t.fk_survey_id
WHERE billable.task_uuid = _task_uuid;
END $$

Expand Down
13 changes: 13 additions & 0 deletions frontend/src/components/Chart/Chart.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,25 @@ import {
} from "recharts";
import "./Chart.css";
import { useSelector } from "react-redux";
// import { useEffect, useState } from "react";

export const Chart = ({ data }) => {
const invoiceDataSource = useSelector(
(state) => state.billingReducer.billingList
);

// const [invoiceDataSource, setDataSource] = useState([]);

// useEffect(() => {
// const seenMap = {};
// const ds = rawDataSource.filter((item) => {
// if (seenMap[item.billable_id]) return false;
// seenMap[item.billable_id] = true;
// return true;
// });
// setDataSource(ds);
// }, [rawDataSource]);

let billingMapping = {};

invoiceDataSource.forEach((invoice) => {
Expand Down
12 changes: 6 additions & 6 deletions frontend/src/components/GenerateInvoice/InvoiceTemplate/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ const InvoiceTemplate = ({ customer, costcenterMap, invoicNum }) => {
function InvoiceDetails({ billingData }) {
let subtotal = 0;
for (let item of billingData) {
subtotal += item.cost;
subtotal += (item.cost * (item.sample_id ? 1 : item.quantity));
}
return (
<>
Expand All @@ -156,15 +156,15 @@ function InvoiceDetails({ billingData }) {

{billingData.map((invoiceItem, index) => {
return (
<tr className="item" key={invoiceItem.billable_id}>
<tr className="item" key={invoiceItem.billable_id + (invoiceItem.sample_id ?? "")}>
<td>
{index + 1}. {invoiceItem.name}
{invoiceItem.name} {invoiceItem.sample_id ? `- ${invoiceItem.sample_id}; ${invoiceItem.authorized_by}` : ""}
</td>
<td>{`SOW-${invoiceItem.task_id ?? (invoiceItem.subtask_id ?? "?")}`}</td>
<td>{`${invoiceItem.task_id ?? (invoiceItem.subtask_id ?? "?")}`}</td>
<td>{invoiceItem.username}</td>
<td>{invoiceItem.quantity}</td>
<td>${(invoiceItem.cost / invoiceItem.quantity).toFixed(2)}</td>
<td>{invoiceItem.sample_id ? 1 : invoiceItem.quantity}</td>
<td>${invoiceItem.cost}</td>
<td>${(invoiceItem.cost * (invoiceItem.sample_id ? 1 : invoiceItem.quantity)).toFixed(2)}</td>
</tr>
);
})}
Expand Down
71 changes: 59 additions & 12 deletions frontend/src/components/InvoiceTable/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@ const InvoiceTable = () => {
const dispatch = useDispatch();
const dataSource = useSelector((state) => state.billingReducer.billingList);
const invoiceList = useSelector((state) => state.billingReducer.invoiceList);
// const [dataSource, setDataSource] = useState([]);

// useEffect(() => {
// const seenMap = {};
// const ds = rawDataSource.filter((item) => {
// if (seenMap[item.billable_id]) return false;
// seenMap[item.billable_id] = true;
// return true;
// });
// setDataSource(ds);
// }, [rawDataSource]);

const columns = [
{
Expand All @@ -20,17 +31,35 @@ const InvoiceTable = () => {
render: (_, record) =>
dataSource.length >= 1 ? (
<div>
<div>SOW-{record.task_id ?? record.fk_task_id ?? record.task_uuid}</div>
{record.subtask_id ? <span className="subtaskInvoiceLabel">Subtask-{record.subtask_id}</span> : null}
<div>
SOW-{record.task_id ?? record.fk_task_id ?? record.task_uuid}
</div>
{record.subtask_id ? (
<span className="subtaskInvoiceLabel">
Subtask-{record.subtask_id}
</span>
) : null}
</div>
) : null,
sorter: (a, b) => (a.task_id ?? a.fk_task_id ?? 0) - (b.task_id ?? b.fk_task_id ?? 0)
sorter: (a, b) =>
(a.task_id ?? a.fk_task_id ?? 0) - (b.task_id ?? b.fk_task_id ?? 0),
},
{
title: "Service",
dataIndex: "name",
key: "name",
editable: false,
render: (_, record) =>
dataSource.length >= 1 ? (
<div>
<div>{record.name}</div>
{record.sample_id ? (
<span className="subtaskInvoiceLabel">
{record.sample_id} - {record.authorized_by}
</span>
) : null}
</div>
) : null,
},
{
title: "Project",
Expand All @@ -56,19 +85,33 @@ const InvoiceTable = () => {
key: "createdDate",
editable: false,
render: (_, record) => {
var options = { year: 'numeric', month: 'long', day: 'numeric' };
var options = { year: "numeric", month: "long", day: "numeric" };
const date = new Date(record.createdDate);
return dataSource.length >= 1 ? (
<div>{date.toLocaleDateString("en-US", options)}</div>
) : null
) : null;
},
sorter: (a, b) => (new Date(a.createdDate).getTime() ?? 0) - (new Date(b.createdDate).getTime() ?? 0),
sorter: (a, b) =>
(new Date(a.createdDate).getTime() ?? 0) -
(new Date(b.createdDate).getTime() ?? 0),
},
{
title: "Cost",
title: "Quantity",
dataIndex: "quantity",
key: "quantity",
editable: false,
render: (_, record) =>
dataSource.length >= 1 ? (
<div>{record.sample_id ? 1 : record.quantity}</div>
) : null,
},
{
title: "Unit Cost",
dataIndex: "cost",
key: "cost",
editable: false,
render: (_, record) =>
dataSource.length >= 1 ? <div>{record.cost}</div> : null,
},
{
title: "Billed",
Expand All @@ -77,10 +120,10 @@ const InvoiceTable = () => {
render: (_, record) => {
return dataSource.length >= 1 ? (
<div>{record.billed ? "Yes" : "No"}</div>
) : null
) : null;
},
},
Table.SELECTION_COLUMN
Table.SELECTION_COLUMN,
];

useEffect(() => {
Expand Down Expand Up @@ -205,11 +248,15 @@ const InvoiceTable = () => {
payload: rowsSelected,
});
},
selectedRowKeys: invoiceList.map((item) => item.billable_id),
selectedRowKeys: invoiceList.map(
(item) => item.billable_id + (item.sample_id ?? "")
),
}}
components={components}
rowKey={(record) => record.billable_id}
rowClassName={(_, index) => index % 2 === 0 ? "editable-row" : "editable-row-dark"}
rowKey={(record) => record.billable_id + (record.sample_id ?? "")}
rowClassName={(_, index) =>
index % 2 === 0 ? "editable-row" : "editable-row-dark"
}
dataSource={dataSource}
columns={renderedColumns}
/>
Expand Down
12 changes: 12 additions & 0 deletions frontend/src/components/InvoiceTotal/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@ import {
const InvoiceTotal = () => {
const dispatch = useDispatch();
const dataSource = useSelector((state) => state.billingReducer.billingList);
// const [dataSource, setDataSource] = useState([]);

// useEffect(() => {
// const seenMap = {};
// const ds = rawDataSource.filter((item) => {
// if (seenMap[item.billable_id]) return false;
// seenMap[item.billable_id] = true;
// return true;
// });
// setDataSource(ds);
// }, [rawDataSource]);

const totalServices = dataSource.length.toString().padStart(1, "0");
let sowMap = {};
let projectMap = {};
Expand Down
76 changes: 0 additions & 76 deletions frontend/src/components/PreviewTable/index.css

This file was deleted.

Loading

0 comments on commit b8ae928

Please sign in to comment.