frontend/src/models/Bin.ts
2026-03-06 10:24:12 -06:00

259 lines
7.3 KiB
TypeScript

import GrainDescriber from "grain/GrainDescriber";
import { cloneDeep } from "lodash";
import { MarkerData } from "maps/mapMarkers/Markers";
import { pond } from "protobuf-ts/pond";
import { getGrainUnit } from "utils";
import { stringToMaterialColour } from "utils/strings";
import { or } from "utils/types";
export class Bin {
public settings: pond.BinSettings = pond.BinSettings.create();
public status: pond.BinStatus = pond.BinStatus.create();
public permissions: pond.Permission[] = [];
public static create(pb?: pond.Bin): Bin {
let my = new Bin();
if (pb) {
my.settings = pond.BinSettings.fromObject(cloneDeep(or(pb.settings, {})));
my.status = pond.BinStatus.fromObject(cloneDeep(or(pb.status, {})));
my.permissions = pb.binPermissions;
}
return my;
}
public static clone(other?: Bin): Bin {
if (other) {
return Bin.create(
pond.Bin.fromObject({
settings: cloneDeep(other.settings),
status: cloneDeep(other.status),
binPermissions: cloneDeep(other.permissions)
})
);
}
return Bin.create();
}
public static any(data: any): Bin {
return Bin.create(pond.Bin.fromObject(cloneDeep(data)));
}
public setLocation(long: number, lat: number): void {
this.settings.location = pond.Location.create();
this.settings.location.longitude = long;
this.settings.location.latitude = lat;
}
public removeLocation(): void {
this.settings.location = null;
}
public binShape(): pond.BinShape | undefined {
return this.settings.specs?.shape;
}
public key(): string {
return this.settings.key;
}
public name(): string {
return this.settings.name !== "" ? this.settings.name : "Bin " + this.key();
}
public grain(): pond.Grain {
let g: pond.Grain = pond.Grain.GRAIN_NONE;
if (this.settings.inventory) {
g = this.settings.inventory.grainType;
}
return g;
}
public getLocation(): pond.Location | null | undefined {
return this.settings.location;
}
public binMapped(): boolean {
let location = this.getLocation();
return (
location !== undefined &&
location !== null &&
location.latitude !== 0 &&
location.longitude !== 0
);
}
public storage(): pond.BinStorage {
return !this.settings.storage
? pond.BinStorage.BIN_STORAGE_SUPPORTED_GRAIN
: this.settings.storage;
}
public customType(): string {
let c = "";
if (this.settings.inventory) {
if (this.settings.inventory.customGrain){
c = this.settings.inventory.customGrain.name
}else{
c = this.settings.inventory.customTypeName;
}
}
return c;
}
public customGrain(): pond.GrainSettings | undefined {
return this.settings.inventory?.customGrain ?? undefined
}
public empty(): boolean {
return this.settings.inventory?.empty || (this.settings.inventory !== undefined && this.settings.inventory !== null && this.bushels() < 5);
}
public objectType(): pond.ObjectType {
return pond.ObjectType.OBJECT_TYPE_BIN;
}
public objectTypeString(): string {
return "Bin";
}
public subtype(): string {
return this.settings.inventory?.grainSubtype ?? "";
}
public grainColour(): string {
let colour = "";
if (this.settings.inventory) {
if (this.grain() === pond.Grain.GRAIN_CUSTOM) {
if (this.customType() !== "") {
colour = stringToMaterialColour(this.customType());
}
} else {
colour = GrainDescriber(this.grain()).colour;
}
}
return colour;
}
public bushels(): number {
let control = this.settings.inventory?.inventoryControl;
let bushels = this.settings.inventory?.grainBushels || 0
if (control === pond.BinInventoryControl.BIN_INVENTORY_CONTROL_AUTOMATIC_LIDAR ||
control === pond.BinInventoryControl.BIN_INVENTORY_CONTROL_LIBRACART){
bushels = this.status.grainBushels
}
return bushels
}
public fillPercent(): number {
let fill = 0;
if (this.settings.inventory && this.settings.specs) {
let bushels = this.settings.inventory.grainBushels
if (this.settings.inventory.inventoryControl === pond.BinInventoryControl.BIN_INVENTORY_CONTROL_AUTOMATIC_LIDAR ||
this.settings.inventory.inventoryControl === pond.BinInventoryControl.BIN_INVENTORY_CONTROL_LIBRACART){
bushels = this.status.grainBushels
}
fill = Math.round(
(bushels / this.settings.specs.bushelCapacity) * 100
);
}
return fill;
}
public grainName(): string {
if (this.grain() !== pond.Grain.GRAIN_INVALID) {
if (this.grain() === pond.Grain.GRAIN_CUSTOM) {
return this.customType();
} else {
return GrainDescriber(this.grain()).name;
}
} else {
return "None";
}
}
public binFillCap(): string {
let fillCap = "";
if (this.settings.specs && this.settings.inventory) {
fillCap = this.settings.inventory.grainBushels + "/" + this.settings.specs.bushelCapacity;
}
return fillCap;
}
public location(): pond.Location | undefined | null {
let loc = this.settings.location;
return loc;
}
public fanID(): number {
return this.settings.fanId;
}
public supportedGrain(): boolean {
let s = false;
if (
this.grain() !== pond.Grain.GRAIN_NONE &&
this.grain() !== pond.Grain.GRAIN_CUSTOM &&
this.grain() !== pond.Grain.GRAIN_INVALID
) {
s = true;
}
return s;
}
public getMarkerData(
clickFunc?: (event: React.PointerEvent<HTMLElement>, index: number, isMobile: boolean) => void,
updateFunc?: (location: pond.Location) => void
): MarkerData {
let m: MarkerData = {
centered: true,
longitude: this.location()?.longitude ?? 0,
latitude: this.location()?.latitude ?? 0,
title: this.name(),
colour: this.grainColour(),
visibleLevels: { min: 17 },
graphPercent: this.fillPercent(),
customSize: this.settings.theme?.height,
details: [this.name() + ", " + this.binFillCap()],
clickFunc: clickFunc,
updateFunc: updateFunc
};
return m;
}
/**
* returns the bushels per tonne set in the bins settings, if not set will return 1
* @returns 1 or bushels per tonne
*/
public bushelsPerTonne(): number {
//trying to avoid a divide by 0 error by only returning a value greater than 0
//since to get the weight you divide the current bushels by the bushels per tonne
let bpt = 1;
if (this.settings.inventory) {
if (this.settings.inventory.bushelsPerTonne > 0) {
bpt = this.settings.inventory.bushelsPerTonne;
}
}
return bpt;
}
public grainInventory(): number {
let grain = this.bushels()
if(getGrainUnit() === pond.GrainUnit.GRAIN_UNIT_TONNE && this.bushelsPerTonne() > 1){
grain = this.bushels() / this.bushelsPerTonne()
}else if (getGrainUnit() === pond.GrainUnit.GRAIN_UNIT_TON && this.bushelsPerTonne() > 1){
grain = this.bushels() / (this.bushelsPerTonne() * 0.907)
}
return Math.round(grain*100)/100
}
/**
* gets the enum value for the inventory control in the bins inventory
*/
public inventoryControl(): pond.BinInventoryControl {
let c = pond.BinInventoryControl.BIN_INVENTORY_CONTROL_UNKNOWN;
if (this.settings.inventory) {
return this.settings.inventory.inventoryControl;
}
return c;
}
}