1
0
forked from a/lifeto-shop
lifeto-shop/src/lib/lifeto/order.ts

227 lines
5.0 KiB
TypeScript
Raw Normal View History

2022-07-07 07:54:36 +00:00
import { LTOApi } from "./api"
import { v4 as uuidv4 } from 'uuid';
import { RefStore } from "../../state/state";
import { debug } from "loglevel";
export const TxnStates = ["PENDING","INFLIGHT","WORKING","ERROR","SUCCESS"] as const
export type TxnState = typeof TxnStates[number]
export interface TxnDetails {
item_uid: string | "galders"
count:number
origin:string
target:string
origin_path:string
target_path:string
}
export abstract class Order {
action_id: string
details?:TxnDetails
created:Date
state: TxnState
constructor(details?:TxnDetails) {
this.state = "PENDING"
this.details = details
this.created = new Date()
this.action_id = uuidv4();
}
mark(t:TxnState) {
this.state = t
}
abstract tick(r:RefStore, api:LTOApi):Promise<any>
abstract status():string
abstract progress():[number, number]
abstract error():string
abstract order_type:OrderType
parse(i:any):Order {
this.action_id = i.action_id
this.details = i.details
this.created = new Date(i.created)
this.state = i.state
return this
}
}
export abstract class BasicOrder extends Order {
stage: number
err?: string
constructor(details:TxnDetails) {
super(details)
this.stage = 0
}
progress():[number,number]{
return [this.stage, 1]
}
status():string {
return this.state
}
error():string {
return this.err ? this.err : ""
}
parse(i:any):BasicOrder {
this.stage = i.stage
this.err = i.err
super.parse(i)
return this
}
}
/// start user defined
export const OrderTypes = ["InvalidOrder","BankItem","InternalXfer"]
export type OrderType = typeof OrderTypes[number]
export class InvalidOrder extends Order{
order_type = "InvalidOrder"
msg:string
constructor(msg: string){
super(undefined)
this.msg = msg
this.mark("ERROR")
}
status():string {
return "ERROR"
}
progress():[number, number] {
return [0,0]
}
error(): string {
return this.msg
}
async tick(r:RefStore, api:LTOApi):Promise<void> {
return
}
parse(i:any):InvalidOrder {
super.parse(i)
this.msg = i.msg
return this
}
}
export interface BasicResponse {
status: number
data: any
msg?: string
}
export interface InternalXferRequest {
item_uid:string
qty:string
account:string
new_char:string
}
export interface InternalXferResponse extends BasicResponse {}
export class InternalXfer extends BasicOrder{
order_type = "InternalXfer"
originalRequest:InternalXferRequest
originalResponse?:InternalXferResponse
constructor(details:TxnDetails) {
super(details)
this.originalRequest = {
item_uid: details.item_uid,
qty: details.count.toString(),
new_char: details.target,
account: details.origin,
}
}
async tick(r:RefStore, api:LTOApi):Promise<void> {
if(this.state !== "PENDING") {
return
}
this.mark("WORKING")
return api.BankAction<InternalXferRequest, InternalXferResponse>("internal-xfer-item",this.originalRequest)
.then((x:InternalXferResponse)=>{
if(x.status == 200){
this.originalResponse = x
this.stage = 1
this.mark("SUCCESS")
const origin_item = r.invs.value.get(this.details?.origin_path!)!.items[this.details?.item_uid!]!
origin_item.item_count = origin_item.item_count - this.details?.count!
r.dirty.value++
}else{
throw x.msg
}
})
.catch((e)=>{
debug("InternalXfer",e)
this.stage = 1
this.err = e
this.mark("ERROR")
})
}
parse(i:any):InternalXfer {
super.parse(i)
this.originalRequest = i.originalRequest
this.originalResponse = i.originalResponse
return this
}
}
export interface BankItemRequest {
item_uid:string
qty:string
account:string
}
export interface BankItemResponse extends BasicResponse {}
export class BankItem extends BasicOrder{
order_type = "BankItem";
originalRequest:BankItemRequest
originalResponse?:BankItemResponse
constructor(details:TxnDetails) {
super(details)
this.originalRequest = {
item_uid: details.item_uid,
qty: details.count.toString(),
account: details.target,
}
}
async tick(r:RefStore, api:LTOApi):Promise<void> {
if(this.state !== "PENDING" ){
return
}
this.mark("WORKING")
return api.BankAction<BankItemRequest, BankItemResponse>("bank-item",this.originalRequest)
.then((x)=>{
debug("BankItem",x)
if(x.status == 200){
this.stage = 1
this.originalResponse = x
this.mark("SUCCESS")
const origin_item = r.invs.value.get(this.details?.origin_path!)!.items[this.details?.item_uid!]!
origin_item.item_count = origin_item.item_count - this.details?.count!
r.dirty.value++
}else {
throw x.msg ? "unknown error" : ""
}
})
.catch((e)=>{
this.stage = 1
this.err = e
this.mark("ERROR")
})
}
parse(i:any):BankItem {
super.parse(i)
this.originalRequest = i.originalRequest
this.originalResponse = i.originalResponse
return this
}
}