works on resolve_claims

This commit is contained in:
2019-10-14 15:27:49 +02:00
parent 0df875d6a6
commit b2e319dc15
4 changed files with 65 additions and 42 deletions

View File

@@ -247,13 +247,7 @@ impl<'q> AsAdmin<'q> {
///
/// When a player gets an item, it's debt is increased by this item sell value
pub fn resolve_claims(self) -> ActionResult<()> {
// Fetch all claims, grouped by items.
let loot = models::item::Loot::owned_by(0).load(self.0)?;
let claims = schema::claims::table
.load::<models::Claim>(self.0)?
.grouped_by(&loot);
// For each claimed item
let data = loot.into_iter().zip(claims).collect::<Vec<_>>();
let data = models::claim::Claims(self.0).grouped_by_loot()?;
dbg!(&data);
for (loot, claims) in data {
@@ -262,18 +256,12 @@ impl<'q> AsAdmin<'q> {
let claim = claims.get(0).unwrap();
let player_id = claim.player_id;
self.0.transaction(|| {
use schema::looted::dsl::*;
diesel::update(looted.find(claim.loot_id))
.set(owner_id.eq(player_id))
loot.set_owner(claim.player_id)
.execute(self.0)?;
diesel::delete(schema::claims::table.find(claim.id))
.execute(self.0)?;
{
use schema::players::dsl::*;
diesel::update(players.find(player_id))
.set(debt.eq(debt + (loot.base_price / 2)))
.execute(self.0)
}
models::player::AsPlayer(self.0, player_id)
.update_debt(loot.sell_value())?;
models::claim::Claims(self.0).remove(player_id, claim.loot_id)?;
Ok(())
})?;
},
_ => (),

View File

@@ -22,49 +22,65 @@ pub struct Claims<'q>(pub &'q DbConnection);
impl<'q> Claims<'q> {
/// Finds a single claim by id.
/// Finds a single claim by association of player and loot ids.
pub fn find(&self, player_id: i32, loot_id: i32) -> QueryResult<Claim> {
Ok(
claims::table
.filter(claims::dsl::player_id.eq(player_id))
.filter(claims::dsl::loot_id.eq(loot_id))
.first(self.0)?
)
.first(self.0)
}
/// Adds a claim in database and returns it
pub fn add(self, player_id: i32, loot_id: i32) -> QueryResult<Claim> {
// We need to validate that the claimed item exists, and is actually owned by group (id 0)
let exists: bool = diesel::select(Loot::exists(loot_id)).get_result(self.0)?;
if !exists {
return Err(diesel::result::Error::NotFound);
};
// We need to validate that the claimed item exists
// AND is actually owned by group (id 0)
let _item = models::item::LootManager(self.0, 0).find(loot_id)?;
let claim = NewClaim::new(player_id, loot_id);
diesel::insert_into(claims::table)
.values(&claim)
.execute(self.0)?;
// Return the created claim
Ok(claims::table.order(claims::dsl::id.desc()).first::<Claim>(self.0)?)
claims::table
.order(claims::dsl::id.desc())
.first::<Claim>(self.0)
}
/// Removes a claim from database, returning it
pub fn remove(self, req_player_id: i32, req_loot_id: i32) -> QueryResult<Claim> {
let claim = self.find(req_player_id, req_loot_id)?;
pub fn remove(self, player_id: i32, loot_id: i32) -> QueryResult<Claim> {
let claim = self.find(player_id, loot_id)?;
diesel::delete(claims::table.find(claim.id))
.execute(self.0)?;
Ok(claim)
}
pub fn filtered_by_loot(&self, loot_id: i32) -> QueryResult<Vec<Claim>> {
claims::table
.filter(claims::dsl::loot_id.eq(loot_id))
.load(self.0)
}
pub(crate) fn grouped_by_loot(&self) -> QueryResult<Vec<(models::item::Loot, Vec<Claim>)>> {
let loot = models::item::Loot::owned_by(0).load(self.0)?;
let claims = claims::table
.load(self.0)?
.grouped_by(&loot);
Ok(
loot.into_iter()
.zip(claims)
.collect::<Vec<_>>()
)
}
}
#[derive(Insertable, Debug)]
#[table_name = "claims"]
pub(crate) struct NewClaim {
struct NewClaim {
player_id: i32,
loot_id: i32,
}
impl NewClaim {
pub(crate) fn new(player_id: i32, loot_id: i32) -> Self {
fn new(player_id: i32, loot_id: i32) -> Self {
Self { player_id, loot_id }
}
}

View File

@@ -10,11 +10,7 @@ type ItemColumns = (looted::id, looted::name, looted::base_price);
const ITEM_COLUMNS: ItemColumns = (looted::id, looted::name, looted::base_price);
type OwnedBy = Select<OwnedLoot, ItemColumns>;
/// Represents a unique item in inventory
///
/// It is also used as a public representation of Loot, since owner
/// information is implicit.
/// Or maybe this is a little too confusing ??
/// Represents a basic item
#[derive(Debug, Queryable, Serialize, Deserialize, Clone)]
pub struct Item {
pub id: i32,
@@ -47,7 +43,10 @@ impl<'q> Inventory<'q> {
type WithOwner = Eq<looted::owner_id, i32>;
type OwnedLoot = Filter<looted::table, WithOwner>;
/// Represents an item that has been looted
/// Represents an item that has been looted,
/// hence has an owner.
#[derive(Identifiable, Debug, Queryable, Serialize)]
#[table_name = "looted"]
pub(super) struct Loot {
@@ -63,13 +62,24 @@ impl Loot {
looted::table.filter(looted::owner_id.eq(id))
}
fn owns(player: i32, item: i32) -> Exists<Find<OwnedLoot, i32>> {
exists(Loot::owned_by(player).find(item))
}
pub(super) fn exists(id: i32) -> Exists<Find<looted::table, i32>> {
exists(looted::table.find(id))
}
pub(crate) fn set_owner(&self, owner: i32) -> () {
diesel::update(looted::table.find(self.id))
.set(looted::dsl::owner_id.eq(owner))
}
/// TODO: should belong inside Item impl
pub(crate) fn value(&self) -> i32 {
self.base_price
}
/// TODO: should belong inside Item impl
pub(crate) fn sell_value(&self) -> i32 {
self.base_price / 2
}
}
/// Manager for a player's loot

View File

@@ -45,6 +45,15 @@ impl<'q> AsPlayer<'q> {
.execute(self.0)?;
Ok(difference)
}
pub fn update_debt(&self, value_in_gp: i32) -> QueryResult<()> {
diesel::update(players::table.find(self.1))
.set(players::dsl::debt.eq(
players::dsl::debt + value_in_gp
))
.execute(self.0)?;
Ok(())
}
}