Skip to content

Commit

Permalink
feat: sketch out a trade_in behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
eseidel committed Mar 21, 2024
1 parent e8bce14 commit 833779f
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 0 deletions.
63 changes: 63 additions & 0 deletions packages/cli/lib/behavior/trade_in.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import 'package:cli/behavior/job.dart';
import 'package:cli/caches.dart';
import 'package:cli/central_command.dart';
import 'package:cli/nav/exploring.dart';
import 'package:cli/net/actions.dart';
import 'package:cli/net/queries.dart';
import 'package:cli/plan/ships.dart';
import 'package:db/db.dart';
import 'package:types/types.dart';

/// Upcycle the ship.
Future<JobResult> doTradeInJob(
BehaviorState state,
Api api,
Database db,
CentralCommand centralCommand,
Caches caches,
Ship ship, {
DateTime Function() getNow = defaultGetNow,
}) async {
// Will also dock the ship.
await visitLocalShipyard(
db,
api,
caches.waypoints,
caches.static,
caches.agent,
ship,
);
// Get the purchase price of a new ship of this type.
final shipType = assertNotNull(
guessShipType(caches.static.shipyardShips, ship),
'No ship type found.',
const Duration(minutes: 5),
);

final price = assertNotNull(
await db.shipyardPriceAt(ship.waypointSymbol, shipType),
'No price found.',
const Duration(minutes: 5),
);

final scrapTransaction = assertNotNull(
await getScrapValue(api, ship.symbol),
'No scrap value found',
const Duration(minutes: 5),
);
final scrapValue = scrapTransaction.totalPrice;
jobAssert(
scrapValue > price.purchasePrice,
'Scrap value is too low.',
const Duration(minutes: 5),
);
// New ships are cheaper than the scrap value, trade in!
await purchaseShip(db, api, caches.agent, ship.waypointSymbol, shipType);
await scrapShipAndLog(api, db, caches.agent, ship);
return JobResult.complete();
}

/// Advance the trade in.
final advanceTradeIn = const MultiJob('Trade In', [
doTradeInJob,
]).run;
7 changes: 7 additions & 0 deletions packages/cli/lib/net/queries.dart
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,13 @@ Future<Market> getMarket(Api api, WaypointSymbol waypointSymbol) async {
return response!.data;
}

/// Fetches Scrap value for a given Ship.
/// Ship must be docked at a shipyard.
Future<ScrapTransaction?> getScrapValue(Api api, ShipSymbol symbol) async {
final response = await api.fleet.getScrapShip(symbol.symbol);
return response?.data.transaction;
}

/// Fetches Construction for a given Waypoint.
Future<Construction> getConstruction(
Api api,
Expand Down
9 changes: 9 additions & 0 deletions packages/db/lib/db.dart
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,15 @@ class Database {
return queryMany(allShipyardPricesQuery(), shipyardPriceFromColumnMap);
}

/// Get the shipyard price for the given waypoint and ship type.
Future<ShipyardPrice?> shipyardPriceAt(
WaypointSymbol waypointSymbol,
ShipType shipType,
) async {
final query = shipyardPriceQuery(waypointSymbol, shipType);
return queryOne(query, shipyardPriceFromColumnMap);
}

/// Add a shipyard price to the database.
Future<void> upsertShipyardPrice(ShipyardPrice price) async {
await execute(upsertShipyardPriceQuery(price));
Expand Down
11 changes: 11 additions & 0 deletions packages/db/lib/src/shipyard_price.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@ Query upsertShipyardPriceQuery(ShipyardPrice price) => Query(
parameters: shipyardPriceToColumnMap(price),
);

/// Query to get the shipyard price for a given waypoint and ship type.
/// Returns null if no price is found.
Query shipyardPriceQuery(WaypointSymbol symbol, ShipType shipType) => Query(
'SELECT * FROM shipyard_price_ '
'WHERE waypoint_symbol = @symbol AND ship_type = @ship_type',
parameters: {
'symbol': symbol.toJson(),
'ship_type': shipType.toJson(),
},
);

/// Query to get the timestamp of the most recent shipyard price for a waypoint.
Query timestampOfMostRecentShipyardPriceQuery(WaypointSymbol symbol) => Query(
'SELECT MAX(timestamp) FROM shipyard_price_ '
Expand Down

0 comments on commit 833779f

Please sign in to comment.