From de0251bc22d554e2ace4d2d3d061dc1054656bcd Mon Sep 17 00:00:00 2001 From: Julien Dessaux Date: Mon, 13 May 2024 23:45:45 +0200 Subject: [node] Big Contracts lib refactoring --- nodejs/lib/contracts.ts | 151 +++++++++++++++++++++++++----------------------- 1 file changed, 79 insertions(+), 72 deletions(-) (limited to 'nodejs/lib/contracts.ts') diff --git a/nodejs/lib/contracts.ts b/nodejs/lib/contracts.ts index 0582cc7..1b54178 100644 --- a/nodejs/lib/contracts.ts +++ b/nodejs/lib/contracts.ts @@ -1,7 +1,6 @@ import { Agent, Cargo, - Contract, } from './types.ts'; import { APIError, @@ -11,84 +10,92 @@ import { } from './api.ts'; import { Ship } from './ships.ts'; import * as dbAgents from '../database/agents.ts'; -import * as dbContracts from '../database/contracts.ts'; - -export async function accept(contract: Contract): Promise { - contract = dbContracts.getContract(contract.id); - if (contract.accepted) return contract; - const response = await send<{agent: Agent, contract: Contract, type: ''}>({endpoint: `/my/contracts/${contract.id}/accept`, method: 'POST'}); - if (response.error) { - debugLog(response); - throw response; - } - dbAgents.setAgent(response.data.agent); - dbContracts.setContract(response.data.contract); - return response.data.contract; -} export async function getContracts(): Promise> { const response = await sendPaginated({endpoint: '/my/contracts'}); - response.forEach(contract => dbContracts.setContract(contract)); - return response; -} - -export async function getContract(contract: Contract): Promise { - try { - return dbContracts.getContract(contract.id); - } catch {} - const response = await send({endpoint: `/my/contracts/${contract.id}`}); - if (response.error) { - debugLog(response); - throw response; - } - dbContracts.setContract(response.data); - return response.data; + return response.map(contract => new Contract(contract)); } -export async function deliver(contract: Contract, ship: Ship): Promise { - contract = dbContracts.getContract(contract.id); - if (contract.terms.deliver[0].unitsRequired <= contract.terms.deliver[0].unitsFulfilled) { - return await fulfill(contract); +export class Contract { + accepted: boolean; + deadlineToAccept: Date; + expiration: Date; + factionSymbol: string; + fulfilled: boolean; + id: string; + terms: { + deadline: Date; + payment: { + onAccepted: number; + onFulfilled: number; + }, + deliver: Array<{ + tradeSymbol: string; + destinationSymbol: string; + unitsRequired: number; + unitsFulfilled: number; + }>; + }; + type: string; + constructor(contract: Contract) { + this.accepted = contract.accepted; + this.deadlineToAccept = contract.deadlineToAccept; + this.expiration = contract.expiration; + this.factionSymbol = contract.factionSymbol; + this.fulfilled = contract.fulfilled; + this.id = contract.id; + this.terms = contract.terms; + this.type = contract.type; } - const tradeSymbol = contract.terms.deliver[0].tradeSymbol; - let units = 0; - ship.cargo.inventory.forEach(i => {if (i.symbol === tradeSymbol) units = i.units; }); - await ship.dock(); // we need to be docked to deliver - const response = await send<{contract: Contract, cargo: Cargo}>({ endpoint: `/my/contracts/${contract.id}/deliver`, method: 'POST', payload: { - shipSymbol: ship.symbol, - tradeSymbol: tradeSymbol, - units: units, - }}); - if (response.error) { - switch(response.error.code) { - case 4503: // contract has expired - // TODO sell cargo? the next trading loop should take care of it by itself - contract.fulfilled = true; - return contract; - case 4509: // contract delivery terms have been met - return await fulfill(contract); - default: // yet unhandled error - debugLog(response); - throw response; + async accept(): Promise { + if (this.accepted) return; + const response = await send<{agent: Agent, contract: Contract, type: ''}>({endpoint: `/my/contracts/${this.id}/accept`, method: 'POST'}); + if (response.error) { + debugLog(response); + throw response; } + dbAgents.setAgent(response.data.agent); } - dbContracts.setContract(response.data.contract); - ship.cargo = response.data.cargo; - if(response.data.contract.terms.deliver[0].unitsRequired <= response.data.contract.terms.deliver[0].unitsFulfilled) { - return await fulfill(response.data.contract); + async deliver(ship: Ship): Promise { + const unitsRemaining = this.terms.deliver[0].unitsRequired - this.terms.deliver[0].unitsFulfilled; + if (unitsRemaining <= 0) return await this.fulfill(); + const tradeSymbol = this.terms.deliver[0].tradeSymbol; + let units = 0; + ship.cargo.inventory.forEach(i => {if (i.symbol === tradeSymbol) units = i.units; }); + if (units === 0) return; + if (units > unitsRemaining) units = unitsRemaining; + await ship.dock(); // we need to be docked to deliver + const response = await send<{contract: Contract, cargo: Cargo}>({ endpoint: `/my/contracts/${this.id}/deliver`, method: 'POST', payload: { + shipSymbol: ship.symbol, + tradeSymbol: tradeSymbol, + units: units, + }}); + if (response.error) { + switch(response.error.code) { + case 4503: // contract has expired + // TODO sell cargo? the next trading loop should take care of it by itself + this.fulfilled = true; + return; + case 4509: // contract delivery terms have been met + return await this.fulfill(); + default: // yet unhandled error + debugLog(response); + throw response; + } + } + ship.cargo = response.data.cargo; + if(response.data.contract.terms.deliver[0].unitsRequired <= response.data.contract.terms.deliver[0].unitsFulfilled) { + return await this.fulfill(); + } } - return response.data.contract; -} - -export async function fulfill(contract: Contract): Promise { - contract = dbContracts.getContract(contract.id); - if (contract.fulfilled) return contract; - const response = await send<{agent: Agent, contract: Contract}>({ endpoint: `/my/contracts/${contract.id}/fulfill`, method: 'POST'}); - if (response.error) { - debugLog(response); - throw response; + async fulfill(): Promise { + if (this.terms.deliver[0].unitsRequired > this.terms.deliver[0].unitsFulfilled) return; + if (this.fulfilled) return; + const response = await send<{agent: Agent, contract: Contract}>({ endpoint: `/my/contracts/${this.id}/fulfill`, method: 'POST'}); + if (response.error) { + debugLog(response); + throw response; + } + dbAgents.setAgent(response.data.agent); } - dbAgents.setAgent(response.data.agent); - dbContracts.setContract(response.data.contract); - return response.data.contract; -} +}; -- cgit v1.2.3