Files
beer-inventory/app/models/history.chart.server.ts
T

207 lines
6.0 KiB
TypeScript

import { enhance } from "@zenstackhq/runtime";
import { random_rgba } from "~/utils/color";
import timeAgo from "~/utils/datetime";
import { db } from "~/utils/db.server";
import { randomRange } from "~/utils/random";
export async function generateMonthChartData(){
const dbe = enhance(db);
// Get the previous month in dates
var dates = [];
const now = Date.now();
const subtracter = (1000 * 60 * 60 * 24);
for(let i = 0; i <= 30; i++){
let date = now - (subtracter * i);
dates.push(new Date(date));
}
dates.reverse();
// Generate labels
const labels = dates.map((date)=> timeAgo(date));
// History of specific drink
const containersWithHistory = await dbe.container.findMany({
include: {drink: true, checkouts: {orderBy: {checkoutAt: "asc"}, where: {checkoutAt: {gte: dates[0]}}}}
})
var datasets : any = [];
for(let container of containersWithHistory){
if(container.checkouts.length == 0) continue;
var history = container.checkouts;
var totalInventory = container.inventory;
// Generate arrays of data
var checkouts = [];
var inventoryAfter = [];
var lastInventoryAfter = history.length > 0 ? history[0].inventoryAfter + 1 : 0;
var previousCheckoutInventoryAfter = history.length > 0 ? history[0].inventoryAfter : 0;
var lastChange = 0;
var previousLastChange = 0;
for(let i = 0; i <= dates.length - 1; i++){
let startDate = dates[i];
let endDate = dates[i+1];
let totalCheckouts = 0;
for(let entry of history){
if(entry.checkoutAt > startDate && entry.checkoutAt < endDate){
totalCheckouts++;
lastInventoryAfter = entry.inventoryAfter;
lastChange = i;
}
}
// There was inventory added
if((lastInventoryAfter + totalCheckouts) > previousCheckoutInventoryAfter){
if(i > 0 && checkouts[i-1] > 0){
// Special case, there were also checkouts the previous day, do nothing
} else if(i > 0) {
let index = randomRange(previousLastChange + 1, i - 1);
for(let j = index; j <= i - 1; j++){
inventoryAfter[j] = lastInventoryAfter + totalCheckouts;
}
}
}
previousCheckoutInventoryAfter = lastInventoryAfter;
previousLastChange = lastChange;
checkouts[i] = totalCheckouts;
inventoryAfter[i] = lastInventoryAfter;
}
// Force the remaining inventory left values after the last checkout to be equal to
// the actual remaining inventory
let index = randomRange(lastChange + 1, dates.length - 1);
for(let i = index; i <= dates.length - 1; i++){
inventoryAfter[i] = totalInventory;
}
let [color1] = random_rgba(1);
datasets.push({
type: 'bar',
label: 'Checkouts ' + container.drink.name,
data: checkouts,
borderColor: color1,
backgroundColor: color1,
});
}
const data = {
labels,
datasets: datasets
};
return data;
}
export async function generate24HChartData(){
const dbe = enhance(db);
// Get the previous month in hours
var hours = [];
const now = Date.now();
const subtracter = (1000 * 60 * 60);
for(let i = 0; i <= 24; i++){
let date = now - (subtracter * i);
hours.push(new Date(date));
}
hours.reverse();
// Generate labels
const labels = hours.map((date)=> timeAgo(date));
// History of specific drink
const containersWithHistory = await dbe.container.findMany({
include: {drink: true, checkouts: {orderBy: {checkoutAt: "asc"}, where: {checkoutAt: {gte: hours[0]}}}}
})
var datasets : any = [];
for(let container of containersWithHistory){
if(container.checkouts.length == 0) continue;
var history = container.checkouts;
var totalInventory = container.inventory;
// Generate arrays of data
var checkouts = [];
var inventoryAfter = [];
var lastInventoryAfter = history.length > 0 ? history[0].inventoryAfter + 1 : 0;
var previousCheckoutInventoryAfter = history.length > 0 ? history[0].inventoryAfter : 0;
var lastChange = 0;
var previousLastChange = 0;
for(let i = 0; i <= hours.length - 1; i++){
let startDate = hours[i];
let endDate = hours[i+1];
let totalCheckouts = 0;
for(let entry of history){
if(entry.checkoutAt > startDate && entry.checkoutAt < endDate){
totalCheckouts++;
lastInventoryAfter = entry.inventoryAfter;
lastChange = i;
}
}
// There was inventory added
if((lastInventoryAfter + totalCheckouts) > previousCheckoutInventoryAfter){
if(i > 0 && checkouts[i-1] > 0){
// Special case, there were also checkouts the previous day, do nothing
} else if(i > 0) {
let index = randomRange(previousLastChange + 1, i - 1);
for(let j = index; j <= i - 1; j++){
inventoryAfter[j] = lastInventoryAfter + totalCheckouts;
}
}
}
previousCheckoutInventoryAfter = lastInventoryAfter;
previousLastChange = lastChange;
checkouts[i] = totalCheckouts;
inventoryAfter[i] = lastInventoryAfter;
}
// Force the remaining inventory left values after the last checkout to be equal to
// the actual remaining inventory
let index = randomRange(lastChange + 1, hours.length - 1);
for(let i = index; i <= hours.length - 1; i++){
inventoryAfter[i] = totalInventory;
}
let [color1] = random_rgba(1);
datasets.push({
type: 'bar',
label: 'Checkouts ' + container.drink.name,
data: checkouts,
borderColor: color1,
backgroundColor: color1,
});
}
const data = {
labels,
datasets: datasets
};
return data;
}