I should be working by now.
This commit is contained in:
1 parent
2715dc20fa
commit
77d0442a3a
3 files changed
+89
-33
No files matched your search
@@ -1,4 +1,4 @@
|
||||
use rusqlite::{ffi, params, Params, Savepoint, Transaction};
|
||||
use rusqlite::{Connection, ffi, params, Params, Savepoint, Transaction};
|
||||
|
||||
use crate::db::{accounts, securities};
|
||||
use crate::db::accounts::{Account, get_account_by_id};
|
||||
@@ -7,15 +7,19 @@ use crate::db::external_id::AccountId;
|
||||
use crate::db::securities::get_security_by_id;
|
||||
use crate::util::*;
|
||||
|
||||
fn _move_securities(tx: &TransactionHelper,
|
||||
fn _move_securities(tx: &Savepoint,
|
||||
cheque: &SecurityEmitterCheque,
|
||||
account_id: &AccountId) -> CustomResult<()> {
|
||||
accounts::add_to_account(tx, &cheque.drawer_account_id, -cheque.amount)?;
|
||||
accounts::add_to_account(tx, account_id, cheque.amount)?;
|
||||
let drawer_receipt = accounts::add_to_account(tx, &cheque.drawer_account_id, -cheque.amount)?;
|
||||
let payee_receipt = accounts::add_to_account(tx, account_id, cheque.amount)?;
|
||||
if drawer_receipt.amount < 0 {
|
||||
let m = format!("Drawer of {:?} does not have sufficient amount in account.", cheque);
|
||||
return Err(Error::InvalidAmount(m));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn _add_cheque_to_cashed_cheques_log(tx: &TransactionHelper,
|
||||
fn _add_cheque_to_cashed_cheques_log(tx: &Connection,
|
||||
cheque: &SecurityEmitterCheque,
|
||||
account_id: &AccountId) -> Result<(), Error> {
|
||||
let q = "
|
||||
@@ -30,7 +34,7 @@ fn _add_cheque_to_cashed_cheques_log(tx: &TransactionHelper,
|
||||
let ret = tx.execute(q, params![cheque.drawer_user_id,
|
||||
cheque.cheque_number,
|
||||
cheque.amount,
|
||||
cheque.security_id]);
|
||||
cheque.security_id]).map_err(Error::SqlError);
|
||||
match ret {
|
||||
Ok(_) => Ok(()),
|
||||
Err(Error::SqlError(rusqlite::Error::SqliteFailure(ffi::Error { code: _, extended_code: 2067 }, _))) =>
|
||||
@@ -39,27 +43,41 @@ fn _add_cheque_to_cashed_cheques_log(tx: &TransactionHelper,
|
||||
}
|
||||
}
|
||||
|
||||
fn cash_cheque(tx: &Transaction,
|
||||
cheque: &SecurityEmitterCheque,
|
||||
account_id: &AccountId) -> CustomResult<()> {
|
||||
if !accounts::is_owner(&tx, &cheque.drawer_account_id, &cheque.drawer_user_id).map_err(Error::SqlError)? {
|
||||
fn cash_cheque_unsafe(savepoint: &Savepoint,
|
||||
cheque: &SecurityEmitterCheque,
|
||||
account_id: &AccountId) -> CustomResult<()> {
|
||||
if cheque.amount < 0 {
|
||||
return Err(Error::InvalidAmount(format!("The cheque {:?} has a negative amount.", cheque)));
|
||||
}
|
||||
if !accounts::is_owner(&savepoint, &cheque.drawer_account_id, &cheque.drawer_user_id).map_err(Error::SqlError)? {
|
||||
return Err(Error::InvalidDrawer(format!("The drawer is the security owner: {:?}", cheque)));
|
||||
}
|
||||
|
||||
if !accounts::is_owner(&tx, account_id, &cheque.payee_user_id).map_err(Error::SqlError)? {
|
||||
if !accounts::is_owner(&savepoint, account_id, &cheque.payee_user_id).map_err(Error::SqlError)? {
|
||||
return Err(Error::InvalidPayee(format!("Trying to cash the cheque {:?} in \
|
||||
an account {:?} that is not owned by the payee.", cheque, account_id)));
|
||||
}
|
||||
|
||||
let myx = TransactionHelper::new(tx);
|
||||
_move_securities(&myx, cheque, account_id)?;
|
||||
_add_cheque_to_cashed_cheques_log(&myx, cheque, account_id)?;
|
||||
|
||||
// savepoint.rollback().map_err(Error::SqlError)?;
|
||||
// create transaction loggetAllPurchaseHistory
|
||||
_move_securities(&savepoint, cheque, account_id)?;
|
||||
_add_cheque_to_cashed_cheques_log(&savepoint, cheque, account_id)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn cash_cheque(tx: &mut Transaction,
|
||||
cheque: &SecurityEmitterCheque,
|
||||
account_id: &AccountId) -> CustomResult<()> {
|
||||
let mut savepoint = tx.savepoint().map_err(Error::SqlError)?;
|
||||
let ret = cash_cheque_unsafe(&savepoint, cheque, account_id);
|
||||
match ret {
|
||||
Err(_) => {
|
||||
savepoint.rollback().map_err(Error::SqlError)?;
|
||||
ret
|
||||
}
|
||||
Ok(_) => {
|
||||
savepoint.commit().map_err(Error::SqlError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_caching_cheques {
|
||||
@@ -115,6 +133,21 @@ mod test_caching_cheques {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_negative_cheque() -> CustomResult<()> {
|
||||
let (mut conn, drawer, payee, payee_account) = setup_basic();
|
||||
let mut tx = conn.transaction().unwrap();
|
||||
|
||||
let cheque = SecurityEmitterCheque::new(
|
||||
drawer, payee, -1000, 99);
|
||||
|
||||
let ret = cash_cheque(&mut tx, &cheque, &payee_account);
|
||||
match ret {
|
||||
Err(Error::InvalidAmount(_)) => Ok(()),
|
||||
_ => Err(Error::Testing("Expected double spending error here.".to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_spend() -> CustomResult<()> {
|
||||
let (mut conn, drawer, payee, payee_account) = setup_basic();
|
||||
|
||||
Reference in new issue
Block a user