Skip to content
Browse files

Working toward the billing statistics displays

  • Loading branch information...
1 parent 0e080fd commit f3418ef6d72af41dec3b0fe63e43b939b4aa294c @tareko committed
View
23 app/Controller/BillingsController.php
@@ -9,10 +9,8 @@ class BillingsController extends AppController {
function index() {
$this->loadModel('BillingsItem');
- debug($this->BillingsItem->distinctShiftsPerDay());
- $log = $this->BillingsItem->getDataSource()->getLog(false, false);
- debug($log);
-
+ $perDay = $this->BillingsItem->distinctPatientsPerDayAnnualAverage(array('healthcare_provider' => 10800));
+ debug ($perDay);
$this->render();
}
/* Upload function
@@ -39,7 +37,7 @@ function export() {
// Find fields needed without recursing through associated models
$data = $this->Billing->find('all', array(
'BillingsItem',
- 'limit' => 1000));
+ 'limit' => 10000));
$data = $this->Billing->recombineBilling($data);
// Define column headers for CSV file, in same array format as the data itself
$headers = array(
@@ -60,5 +58,20 @@ function export() {
// Make the data available to the view (and the resulting CSV file)
$this->set(compact('data'));
}
+
+ function patientsPerDay() {
+ $this->loadModel('BillingsItem');
+ $data = $this->BillingsItem->distinctPatientsPerDay();
+ $headers = array(
+ 'healthcare_provider' => 'Provider',
+ 'service_date' => 'Service date',
+ 'COUNT(DISTINCT billing_id)' => 'Unique patients seen',
+ );
+ // Add headers to start of data array
+ array_unshift($data,$headers);
+ $this->set('data', $data);
+ $this->render();
+ }
+
}
?>
View
2 app/Controller/TradesController.php
@@ -72,7 +72,7 @@ public function add() {
$recipientNotPresent = false;
$originatorNotPresent = false;
$checkDuplicate = false;
- if ($this->request->is('post') && $this->request->data) {
+ if ($this->request->isPost() && $this->request->data) {
if (isset($this->request->data['Trade']['shift_id']) && isset($this->request->data['Trade']['user_id'])) {
$checkDuplicate = $this->checkDuplicate($this->request->data['Trade']['shift_id'], $this->request->data['Trade']['user_id']);
}
View
29 app/Model/BillingsItem.php
@@ -52,13 +52,38 @@ public function dateFormatBeforeSave($dateString) {
return date('Y-m-d', strtotime($dateString));
}
- public function distinctShiftsPerDay ($conditions = array()) {
+ public function distinctPatientsPerDay ($conditions = array()) {
+ $i = 0;
$data = $this->find('all', array(
'fields' => array('Billing.healthcare_provider', 'service_date', 'COUNT(DISTINCT billing_id)'),
'conditions' => $conditions,
'group' => array('Billing.healthcare_provider', 'service_date')
)
);
- return $data;
+ foreach ($data as $row) {
+ $output[$i]['healthcare_provider'] = $row['Billing']['healthcare_provider'];
+ $output[$i]['service_date'] = $row['BillingsItem']['service_date'];
+ $output[$i]['count'] = $row[0]['COUNT(DISTINCT billing_id)'];
+ $i = $i + 1;
+ }
+ return $output;
}
+
+ public function distinctPatientsPerDayAnnualAverage ($conditions = array()) {
+ $i = 0;
+ $data = $this->find('all', array(
+ 'fields' => array('Billing.healthcare_provider', 'service_date', 'COUNT(DISTINCT billing_id)'),
+ 'conditions' => $conditions,
+ 'group' => array('Billing.healthcare_provider', 'service_date')
+ )
+ );
+ foreach ($data as $row) {
+ $output[$i]['healthcare_provider'] = $row['Billing']['healthcare_provider'];
+ $output[$i]['service_date'] = $row['BillingsItem']['service_date'];
+ $output[$i]['count'] = $row[0]['COUNT(DISTINCT billing_id)'];
+ $i = $i + 1;
+ }
+ return $output;
+ }
+
}
View
8 app/View/Billings/csv/export.ctp
@@ -2,12 +2,6 @@
// Loop through the data array
foreach ($data as $row)
{
- // Loop through every value in a row
- foreach ($row as $value)
- {
- // Apply opening and closing text delimiters to every value
- $value = "\"".$value."\"";
- }
// Echo all values in a row comma separated
- echo implode(",",$row)."\n";
+ echo implode(",",$row)."\n";
}
View
7 app/View/Billings/csv/patients_per_day.ctp
@@ -0,0 +1,7 @@
+<?php
+// Loop through the data array
+foreach ($data as $row)
+{
+ // Echo all values in a row comma separated
+ echo implode(",",$row)."\n";
+}
View
261 app/View/Billings/index.ctp
@@ -1,140 +1,121 @@
-<style>
-
-svg {
- font: 10px sans-serif;
-}
-
-path {
- fill: steelblue;
-}
-
-.axis path,
-.axis line {
- fill: none;
- stroke: #000;
- shape-rendering: crispEdges;
-}
-
-.brush .extent {
- stroke: #fff;
- fill-opacity: .125;
- shape-rendering: crispEdges;
-}
-
-</style>
-<script src="http://d3js.org/d3.v3.min.js"></script>
-<script>
-
-var margin = {
- top: 10, right: 10, bottom: 100, left: 40},
- margin2 = {
- top: 430, right: 10, bottom: 20, left: 40},
- width = 960 - margin.left - margin.right,
- height = 500 - margin.top - margin.bottom,
- height2 = 500 - margin2.top - margin2.bottom;
-
- var parseDate = d3.time.format("%b %Y").parse;
-
- var x = d3.time.scale().range([0, width]),
- x2 = d3.time.scale().range([0, width]),
- y = d3.scale.linear().range([height, 0]),
- y2 = d3.scale.linear().range([height2, 0]);
-
- var xAxis = d3.svg.axis().scale(x).orient("bottom"),
- xAxis2 = d3.svg.axis().scale(x2).orient("bottom"),
- yAxis = d3.svg.axis().scale(y).orient("left");
-
- var brush = d3.svg.brush()
- .x(x2)
- .on("brush", brush);
-
- var area = d3.svg.area()
- .interpolate("monotone")
- .x(function(d) {
- return x(d.date);
- })
- .y0(height)
- .y1(function(d) {
- return y(d.price);
- });
-
- var area2 = d3.svg.area()
- .interpolate("monotone")
- .x(function(d) {
- return x2(d.date);
- })
- .y0(height2)
- .y1(function(d) {
- return y2(d.price);
- });
-
- var svg = d3.select("body").append("svg")
- .attr("width", width + margin.left + margin.right)
- .attr("height", height + margin.top + margin.bottom);
-
- svg.append("defs").append("clipPath")
- .attr("id", "clip")
- .append("rect")
- .attr("width", width)
- .attr("height", height);
-
- var focus = svg.append("g")
- .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
-
- var context = svg.append("g")
- .attr("transform", "translate(" + margin2.left + "," + margin2.top + ")");
-
- d3.csv("http://127.0.0.1/sp500.csv", function(error, data) {
-
- data.forEach(function(d) {
- d.date = parseDate(d.date);
- d.price = +d.price;
- });
-
- x.domain(d3.extent(data.map(function(d) {
- return d.date;
- })));
- y.domain([0, d3.max(data.map(function(d) {
- return d.price;
- }))]);
- x2.domain(x.domain());
- y2.domain(y.domain());
-
- focus.append("path")
- .datum(data)
- .attr("clip-path", "url(#clip)")
- .attr("d", area);
-
- focus.append("g")
- .attr("class", "x axis")
- .attr("transform", "translate(0," + height + ")")
- .call(xAxis);
-
- focus.append("g")
- .attr("class", "y axis")
- .call(yAxis);
-
- context.append("path")
- .datum(data)
- .attr("d", area2);
-
- context.append("g")
- .attr("class", "x axis")
- .attr("transform", "translate(0," + height2 + ")")
- .call(xAxis2);
-
- context.append("g")
- .attr("class", "x brush")
- .call(brush)
- .selectAll("rect")
- .attr("y", -6)
- .attr("height", height2 + 7);
- });
-
- function brush() {
- x.domain(brush.empty() ? x2.domain() : brush.extent());
- focus.select("path").attr("d", area);
- focus.select(".x.axis").call(xAxis);
- }
-
- </script>
+In your whole career, you saw: <?php $total_patients ?> patients
+Your annual average is: <?php $annual_average ?> patients
+Your daily average is: <?php $daily_average ?> patients
+
+The group daily average is:
+
+
+<!-- <style>
+body {
+ font: 10px sans-serif;
+}
+
+.axis path,
+.axis line {
+ fill: none;
+ stroke: #000;
+ shape-rendering: crispEdges;
+}
+
+.dot {
+ stroke: #000;
+}
+
+</style>
+<script src="http://d3js.org/d3.v3.min.js"></script>
+<script>
+
+var margin = {top: 20, right: 20, bottom: 30, left: 40},
+ width = 960 - margin.left - margin.right,
+ height = 500 - margin.top - margin.bottom;
+
+var x = d3.time.scale()
+ .range([0, width]);
+
+var y = d3.scale.linear()
+ .range([height, 0]);
+
+var color = d3.scale.category10();
+
+var xAxis = d3.svg.axis()
+ .scale(x)
+ .orient("bottom");
+
+var yAxis = d3.svg.axis()
+ .scale(y)
+ .orient("left");
+
+var svg = d3.select("body").append("svg")
+ .attr("width", width + margin.left + margin.right)
+ .attr("height", height + margin.top + margin.bottom)
+ .append("g")
+ .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
+
+d3.csv("http://127.0.0.1/kitab/billings/patientsPerDay.csv", function(error, data) {
+
+ data = data.map( function (d) {
+ return {
+ provider: +d.Provider, // the + sign will coerce strings to number values
+ date: new Date(d['Service date']),
+ patients: +d['Unique patients seen'] };
+ });
+
+ providers = d3.nest().key(function(d) { return d.provider; }).entries(data);
+
+ x.domain(d3.extent(data, function(d) { return d.date; })).nice();
+ y.domain(d3.extent(data, function(d) { return d.patients; })).nice();
+
+ svg.append("g")
+ .attr("class", "x axis")
+ .attr("transform", "translate(0," + height + ")")
+ .call(xAxis)
+ .append("text")
+ .attr("class", "label")
+ .attr("x", width)
+ .attr("y", -6)
+ .style("text-anchor", "end")
+ .text("Sepal Width (cm)");
+
+ svg.append("g")
+ .attr("class", "y axis")
+ .call(yAxis)
+ .append("text")
+ .attr("class", "label")
+ .attr("transform", "rotate(-90)")
+ .attr("y", 6)
+ .attr("dy", ".71em")
+ .style("text-anchor", "end")
+ .text("Sepal Length (cm)")
+
+ svg.selectAll(".dot")
+ .data(data)
+ .enter().append("circle")
+ .attr("class", "dot")
+ .attr("r", 3.5)
+ .attr("cx", function(d) { return x(d.date); })
+ .attr("cy", function(d) { return y(d.patients); })
+ .style("fill", function(d) { return color(d.provider); });
+
+ var legend = svg.selectAll(".legend")
+ .data(color.domain())
+ .enter().append("g")
+ .attr("class", "legend")
+ .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
+
+ legend.append("rect")
+ .attr("x", width - 18)
+ .attr("width", 18)
+ .attr("height", 18)
+ .style("fill", color);
+
+ legend.append("text")
+ .attr("x", width - 24)
+ .attr("y", 9)
+ .attr("dy", ".35em")
+ .style("text-anchor", "end")
+ .text(function(d) { return d; });
+
+});
+
+</script>
+-->

0 comments on commit f3418ef

Please sign in to comment.
Something went wrong with that request. Please try again.