Created
February 27, 2023 18:41
-
-
Save symbioquine/ac955c450ce4f4602458f22c365eea87 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script setup> | |
import { ref, inject, onMounted } from 'vue'; | |
import { formatRFC3339, uuidv4 } from "assetlink-plugin-api"; | |
import { useRouter } from 'vue-router' | |
const router = useRouter(); | |
const assetLink = inject('assetLink'); | |
const litersUnitTerm = ref(undefined); | |
const dieselInStorageTankAsset = ref(undefined); | |
const loadingPrerequisites = ref(true); | |
const LITERS_UNIT_NAME = "liters"; | |
const MATERIAL_TYPE_NAME = "diesel"; | |
const DIESEL_IN_STORAGE_TANK_NAME = "Diesel in Storage Tank"; | |
const getOrCreateEntityByName = async (type, name, rels) => { | |
const results = await assetLink.entitySource.query(q => q | |
.findRecords(type) | |
.filter({ attribute: 'name', op: 'equal', value: name })) | |
const existingValue = (results || []).find(e => e); | |
if (existingValue) { | |
return existingValue; | |
} | |
const termToCreate = { | |
type: type, | |
id: uuidv4(), | |
attributes: { | |
name, | |
}, | |
relationships: { | |
...(rels || {}), | |
}, | |
}; | |
return await assetLink.entitySource.update( | |
(t) => t.addRecord(termToCreate), | |
{label: `Add '${name}' ${type} term`}); | |
}; | |
const loadPrerequisites = async () => { | |
await assetLink.booted; | |
litersUnitTerm.value = await getOrCreateEntityByName('taxonomy_term--unit', LITERS_UNIT_NAME); | |
const dieselMaterialType = await getOrCreateEntityByName('taxonomy_term--material_type', MATERIAL_TYPE_NAME); | |
dieselInStorageTankAsset.value = await getOrCreateEntityByName('asset--material', DIESEL_IN_STORAGE_TANK_NAME, { | |
material_type: { | |
data: { type: dieselMaterialType.type, id: dieselMaterialType.id }, | |
}, | |
}); | |
loadingPrerequisites.value = false; | |
}; | |
onMounted(() => loadPrerequisites()); | |
const refilledTractor = ref(undefined); | |
const refilledQuantity = ref(0); | |
// This shouldn't actually be necessary, probably at least one bug preventing this from working | |
// automatically, but this work-around works for now | |
const hackRefreshStorageTankAsset = async () => { | |
await assetLink.entitySource.query(q => q | |
.findRecord({ type: dieselInStorageTankAsset.value.type, id: dieselInStorageTankAsset.value.id }), | |
{ forceRemote: true }); | |
assetLink.eventBus.$emit(`changed:asset`, { assetType: dieselInStorageTankAsset.value.type, assetId: dieselInStorageTankAsset.value.id }); | |
}; | |
const onRefilledTractor = async () => { | |
if (!refilledQuantity.value) { | |
return; | |
} | |
const quantity = { | |
type: 'quantity--standard', | |
id: uuidv4(), | |
attributes: { | |
measure: 'volume', | |
value: { | |
decimal: `${refilledQuantity.value}`, | |
}, | |
inventory_adjustment: 'decrement', | |
}, | |
relationships: { | |
inventory_asset: { | |
data: { | |
type: dieselInStorageTankAsset.value.type, | |
id: dieselInStorageTankAsset.value.id, | |
} | |
}, | |
units: { | |
data: { | |
type: litersUnitTerm.value.type, | |
id: litersUnitTerm.value.id, | |
} | |
}, | |
}, | |
}; | |
const activityLog = { | |
type: 'log--activity', | |
attributes: { | |
name: `Refill ${dieselInStorageTankAsset.value.attributes.name}`, | |
timestamp: formatRFC3339(new Date()), | |
status: "done", | |
}, | |
relationships: { | |
quantity: { | |
data: [ | |
{ | |
type: quantity.type, | |
id: quantity.id, | |
}, | |
] | |
}, | |
asset: { | |
data: [ | |
{ | |
type: refilledTractor.value.type, | |
id: refilledTractor.value.id, | |
}, | |
] | |
}, | |
}, | |
}; | |
await assetLink.entitySource.update( | |
(t) => [ | |
t.addRecord(quantity), | |
t.addRecord(activityLog), | |
], | |
{label: `Record ${activityLog.attributes.name}`}); | |
await hackRefreshStorageTankAsset(); | |
refilledQuantity.value = 0; | |
}; | |
const onRefilledContainer = async () => { | |
const quantity = { | |
type: 'quantity--standard', | |
id: uuidv4(), | |
attributes: { | |
measure: 'volume', | |
value: { | |
decimal: `${3000}`, | |
}, | |
inventory_adjustment: 'reset', | |
}, | |
relationships: { | |
inventory_asset: { | |
data: { | |
type: dieselInStorageTankAsset.value.type, | |
id: dieselInStorageTankAsset.value.id, | |
} | |
}, | |
units: { | |
data: { | |
type: litersUnitTerm.value.type, | |
id: litersUnitTerm.value.id, | |
} | |
}, | |
}, | |
}; | |
const activityLog = { | |
type: 'log--activity', | |
attributes: { | |
name: `Refill ${dieselInStorageTankAsset.value.attributes.name}`, | |
timestamp: formatRFC3339(new Date()), | |
status: "done", | |
}, | |
relationships: { | |
quantity: { | |
data: [ | |
{ | |
type: quantity.type, | |
id: quantity.id, | |
}, | |
] | |
}, | |
}, | |
}; | |
await assetLink.entitySource.update( | |
(t) => [ | |
t.addRecord(quantity), | |
t.addRecord(activityLog), | |
], | |
{label: `Record ${activityLog.attributes.name}`}); | |
await hackRefreshStorageTankAsset(); | |
}; | |
const getCurrentDieselInventory = (asset) => { | |
if (!asset) { | |
return 0; | |
} | |
const lineItem = (asset.attributes?.inventory || []).find(item => item.measure === 'volume' && item.units === LITERS_UNIT_NAME); | |
return parseInt(lineItem?.value || '0'); | |
}; | |
</script> | |
<template alink-route[com.example.farmos_asset_link.routes.v0.diesel_tracking_page]="/diesel-tracking"> | |
<q-page padding class="text-left"> | |
<h4 class="q-mt-xs q-mb-lg">{{ DIESEL_IN_STORAGE_TANK_NAME }}</h4> | |
<entity-select | |
label="Tractor" | |
hint="Which tractor was fueled?" | |
entity-type="asset" | |
:entity-bundles="['equipment']" | |
v-model="refilledTractor" | |
class="q-mt-md" | |
></entity-select> | |
<q-input | |
filled | |
type="number" | |
v-model.number="refilledQuantity" | |
suffix="L" | |
label="Quantity" | |
hint="How much was used?" | |
class="q-mt-md" | |
> | |
</q-input> | |
<q-btn | |
@click="onRefilledTractor" | |
:disabled="!refilledTractor || refilledQuantity <= 0" | |
color="secondary" | |
class="row full-width q-mt-md">Fill Up</q-btn> | |
<div class="full-width row justify-center half-gauge q-mt-md" v-if="dieselInStorageTankAsset"> | |
<entity-resolver | |
entity-type="asset" | |
:entity-ref="dieselInStorageTankAsset.id" | |
#default="{ entity }" | |
:key="dieselInStorageTankAsset.id"> | |
<q-circular-progress | |
:min="0" | |
:max="3000 * 2" | |
:value="getCurrentDieselInventory(entity)" | |
show-value | |
size="200px" | |
font-size="14px" | |
:thickness="0.1" | |
color="orange" | |
track-color="grey-3" | |
:angle="-90" | |
> | |
<div>{{ getCurrentDieselInventory(entity) }}</div> | |
<div><small class="text-negative"> of 3000</small></div> | |
</q-circular-progress> | |
</entity-resolver> | |
</div> | |
<q-btn @click="onRefilledContainer" color="secondary" class="row full-width q-mt-md">Refilled Container</q-btn> | |
<q-btn @click="() => router.back()" color="positive" class="row full-width q-mt-md">Back</q-btn> | |
<q-inner-loading :showing="loadingPrerequisites"></q-inner-loading> | |
</q-page> | |
</template> | |
<style> | |
/* Based on https://codepen.io/anon/pen/NJmzEG?editors=1100 */ | |
.half-gauge { | |
padding-bottom: 110px; | |
} | |
.half-gauge svg { | |
clip-path: inset(50% 0% 0% 0%); | |
} | |
.half-gauge > * { | |
margin-bottom: -50% | |
} | |
.half-gauge .q-circular-progress__text { | |
text-align: center; | |
top: 35%; | |
transform: translate3d(0, -50%, 0); | |
flex-direction: column; | |
} | |
</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
2023_02_27_diesel_tracking_plugin_demo.webm