Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WiP] implications #151

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
2 changes: 1 addition & 1 deletion loadenv.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
} else {
$envFileDir = __DIR__;
}
echo "Looking for .env in $envFileDir\n";
// echo "Looking for .env in $envFileDir\n";
$dotenv = Dotenv\Dotenv::createImmutable($envFileDir);
$dotenv->load();
18 changes: 15 additions & 3 deletions schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,29 @@ function getTables()
"create table movements (
id SERIAL PRIMARY KEY,
userId integer,
type_ varchar(54), /* 'invoice', 'payment', 'worked' */
type_ varchar(54), /* DEPRECATED */
fromComponent integer,
toComponent integer,
timestamp_ timestamp,
amount decimal
amount decimal,
unit varchar,
subIndex integer default 0,
deleted boolean default false
);",

"drop table if exists implications;",
"create table implications (
id SERIAL PRIMARY KEY,
userId integer,
relation varchar(54), /* 'inner', 'outer', 'delivery', 'consumption', 'production' */
statementId integer,
movementId integer
);",

"drop table if exists statements;",
"create table statements (
id SERIAL PRIMARY KEY,
movementId integer,
movementId integer, /* DEPRECATED */
userId integer,
sourceDocumentFormat varchar, /* could be an invoice, bank statement csv file, API call etc */
sourceDocumentFilename varchar, /* TODO: work out how to store files when on Heroku */
Expand Down
19 changes: 16 additions & 3 deletions schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,31 @@ drop table if exists movements;
create table movements (
id SERIAL PRIMARY KEY,
userId integer,
type_ varchar(54), /* 'invoice', 'payment', 'worked' */
type_ varchar(54), /* DEPRECATED */
fromComponent integer,
toComponent integer,
timestamp_ timestamp,
amount decimal
amount decimal,
unit varchar,
subIndex integer default 0,
deleted boolean default false
);

drop table if exists implications;

create table implications (
id SERIAL PRIMARY KEY,
userId integer,
relation varchar(54), /* 'inner', 'outer', 'delivery', 'consumption', 'production' */
statementId integer,
movementId integer
);

drop table if exists statements;

create table statements (
id SERIAL PRIMARY KEY,
movementId integer,
movementId integer, /* DEPRECATED */
userId integer,
sourceDocumentFormat varchar, /* could be an invoice, bank statement csv file, API call etc */
sourceDocumentFilename varchar, /* TODO: work out how to store files when on Heroku */
Expand Down
36 changes: 36 additions & 0 deletions src/commands/budgets-tool.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);
require_once(__DIR__ . '/../database.php');
function budgetsTool($context, $command)
{
if (isset($context["user"])) {
$conn = getDbConn();
$consumptionRes = $conn->executeQuery('SELECT ' .
'm.timestamp_, m.amount, m.unit, c1.name as from, c2.name as to, s.description ' .
'FROM movements m INNER JOIN implications i ON i.movementId = m.id ' .
'INNER JOIN components c1 ON m.fromComponent = c1.id ' .
'INNER JOIN components c2 ON m.toComponent = c2.id ' .
'INNER JOIN statements s ON i.statementId = s.id ' .
'WHERE i.relation=\'purchase-delivery\'');
$movements = $consumptionRes->fetchAllAssociative();
function cmp($a, $b)
{
if ($a["amount"] == $b["amount"]) {
return 0;
}
return ($a["amount"] < $b["amount"]) ? -1 : 1;
}
usort($movements, "cmp");

$ret = [];
for ($i = 0; $i < count($movements); $i++) {
if ((!isset($command[1])) || ($command[1] == $movements[$i]["to"])) {
array_push($ret, $movements[$i]["timestamp_"] . " " . $movements[$i]["amount"] . " " . $movements[$i]["to"] . " " . $movements[$i]["from"] . " " . $movements[$i]["description"]);
}
}
return $ret;
} else {
return [ "User not found or wrong password" ];
}
}
3 changes: 2 additions & 1 deletion src/commands/enter.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ function enter($context, $command)
strval($componentFromId),
strval($componentToId),
$dateStr,
$amountStr
$amountStr,
'EUR'
])[0]);
$statementId = intval(createStatement($context, [
"create-statement",
Expand Down
82 changes: 82 additions & 0 deletions src/commands/expenses-overview.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php

declare(strict_types=1);
require_once(__DIR__ . '/../database.php');
function expensesOverview($context, $command)
{
if (isset($context["user"])) {
$conn = getDbConn();
$consumptionRes = $conn->executeQuery('SELECT ' .
'm.timestamp_, m.amount, m.unit, c1.name as from, c2.name as to, s.description ' .
'FROM movements m INNER JOIN implications i ON i.movementId = m.id ' .
'INNER JOIN components c1 ON m.fromComponent = c1.id ' .
'INNER JOIN components c2 ON m.toComponent = c2.id ' .
'INNER JOIN statements s ON i.statementId = s.id ' .
'WHERE i.relation=\'purchase-delivery\'');
$movements = $consumptionRes->fetchAllAssociative();
$months = [];
$columns = [ "month", "total" ];
for ($i = 0; $i < count($movements); $i++) {
$month = substr($movements[$i]["timestamp_"], 0, 7);
// var_dump(["month", $month]);
if (!isset($months[$month])) {
$months[$month] = [
];
}
// var_dump(["budget this month", $movements[$i]["to"]]);
$budget = $movements[$i]["to"];
if (!isset($months[$month][$budget])) {
$months[$month][$budget] = [];
if (!in_array($budget, $columns)) {
$columns[] = $budget;
}
}
array_push($months[$month][$movements[$i]["to"]], $movements[$i]);
}
$ret = [];
$overallSum = 0;
$overallNum = 0;

// $ret = [ implode(" | ", $columns), "" ];
foreach ($months as $month => $budgets) {
$monthSum = 0;
foreach ($budgets as $budget => $entries) {
for ($i = 0; $i < count($entries); $i++) {
if (($entries[$i]["to"] != "Decla") && ($entries[$i]["to"] != "Self")) {
$monthSum += $entries[$i]["amount"];
}
}
}
$overallNum++;
$overallSum += $monthSum;
array_push($ret, "### " . $month . " " . $monthSum);

foreach ($budgets as $budget => $entries) {
$sum = 0;
for ($i = 0; $i < count($entries); $i++) {
if (($entries[$i]["to"] != "Decla") && ($entries[$i]["to"] != "Self")) {
$sum += $entries[$i]["amount"];
}
}
array_push($ret, "#### " . $budget . " " . $sum);
array_push($ret, "```" );
for ($i = 0; $i < count($entries); $i++) {
array_push($ret, " (" .
substr($entries[$i]["timestamp_"], 8, 2) . ") [" .
$entries[$i]["amount"] . " " .
$entries[$i]["unit"] . "] " .
$entries[$i]["from"] . " | " .
$entries[$i]["description"] . " "
);
}
array_push($ret, "```" );
array_push($ret, "" );
}
array_push($ret, "" );
}
array_push($ret, "$overallSum in $overallNum months is " . ($overallSum / $overallNum) . " on average.");
return $ret;
} else {
return [ "User not found or wrong password" ];
}
}
26 changes: 15 additions & 11 deletions src/commands/helpers/createMovement.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,16 @@ function createMovement($context, $command)
"fromComponent" => intval($command[3]),
"toComponent" => intval($command[4]),
"timestamp_" => timestampToDateTime(intval($command[5])),
"amount" => floatval($command[6])
"amount" => floatval($command[6]),
"unit" => $command[7]
];

if (!$context["adminParty"]) {
checkAccess($params["fromComponent"], $params["userId"]);
}

$query = "INSERT INTO movements (userId, type_, fromComponent, toComponent, timestamp_, amount) "
. "VALUES (:userId, :type_, :fromComponent, :toComponent, :timestamp_, :amount);";
$query = "INSERT INTO movements (userId, type_, fromComponent, toComponent, timestamp_, amount, unit) "
. "VALUES (:userId, :type_, :fromComponent, :toComponent, :timestamp_, :amount, :unit);";

$ret = $conn->executeStatement($query, $params);
return [ strval($conn->lastInsertId()) ];
Expand All @@ -48,7 +49,8 @@ function updateMovement($context, $command) {
"fromComponent" => intval($command[3]),
"toComponent" => intval($command[4]),
"timestamp_" => timestampToDateTime(intval($command[5])),
"amount" => floatval($command[6])
"amount" => floatval($command[6]),
"unit" => $command[7]
];

if (!$context["adminParty"]) {
Expand Down Expand Up @@ -89,7 +91,8 @@ function ensureMovementsLookalikeGroup($context, $movement, $numNeeded)
"toComponent" => $movement["toComponent"],
"mintimestamp_" => timestampToDateTime($movement["timestamp_"] - 12 * 3600),
"maxtimestamp_" => timestampToDateTime($movement["timestamp_"] + 12 * 3600),
"amount" => $movement["amount"]
"amount" => $movement["amount"],
"unit" => $movement["unit"]
];
$ret = $conn->executeQuery($query, $fields);
$ass = $ret->fetchAllAssociative();
Expand All @@ -107,16 +110,17 @@ function ensureMovementsLookalikeGroup($context, $movement, $numNeeded)
} elseif (count($arr) == $numNeeded) {
// echo ("Already have $numNeeded movements with these details!\n");
} else {
$query = "INSERT INTO movements (type_, fromComponent, toComponent, timestamp_, amount) "
. "VALUES (:type_, :fromComponent, :toComponent, :timestamp_, :amount);";
$query = "INSERT INTO movements (type_, fromComponent, toComponent, timestamp_, amount, unit) "
. "VALUES (:type_, :fromComponent, :toComponent, :timestamp_, :amount, :unit);";
$numToAdd = $numNeeded - count($arr);
for ($i = 0; $i < $numToAdd; $i++) {
$conn->executeStatement($query, [
"type_" => $movement["type_"],
"fromComponent" => $movement["fromComponent"],
"toComponent" => $movement["toComponent"],
"timestamp_" => timestampToDateTime($movement["timestamp_"]),
"amount" => $movement["amount"]
"amount" => $movement["amount"],
"unit" => $movement["unit"]
]);
$created = $conn->lastInsertId();
// echo("Movement $created was created\n");
Expand All @@ -126,12 +130,12 @@ function ensureMovementsLookalikeGroup($context, $movement, $numNeeded)
return $arr;
}

function createMultipleMovement($userId, $type_, $fromComponent, $toComponent, $timestamp_, $amount)
function createMultipleMovement($userId, $type_, $fromComponent, $toComponent, $timestamp_, $amount, $unit)
{
$conn = getDbConn();
$conn->executeQuery(
"INSERT INTO movements (userId, type_, fromComponent, toComponent,timestamp_, amount) VALUES (:userId, :type_, :fromComponent, :toComponent, :timestamp_,:amount) ",
[ "userId" => $userId, "type_" => $type_, "fromComponent" => $fromComponent, "toComponent" => $toComponent, "timestamp_" => $timestamp_, "amount" => $amount]
"INSERT INTO movements (userId, type_, fromComponent, toComponent,timestamp_, amount, unit) VALUES (:userId, :type_, :fromComponent, :toComponent, :timestamp_,:amount, :unit) ",
[ "userId" => $userId, "type_" => $type_, "fromComponent" => $fromComponent, "toComponent" => $toComponent, "timestamp_" => $timestamp_, "amount" => $amount, "unit" => $unit]
);
return [ strval($conn->lastInsertId()) ];
}
Loading