Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
180 changes: 82 additions & 98 deletions stellar-contracts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@
}

#[contracttype]
pub enum GroomingKey {
GroomingRecord(u64),
GroomingRecordCount,
PetGroomingCount(u64),
PetGroomingIndex((u64, u64)),
pub enum BreedingKey {
BreedingRecord(u64),
BreedingRecordCount,
PetBreedingCount(u64),
PetBreedingIndex((u64, u64)),
PetOffspringCount(u64),
PetOffspringIndex((u64, u64)),
}

#[cfg(test)]
Expand All @@ -50,7 +52,7 @@
mod test_behavior;
#[cfg(test)]
mod test_emergency_contacts;
#[cfg(test)]

Check warning on line 55 in stellar-contracts/src/lib.rs

View workflow job for this annotation

GitHub Actions / review

Diff in /home/runner/work/PetChain-Contracts/PetChain-Contracts/stellar-contracts/src/lib.rs
mod test_emergency_override;
#[cfg(test)]
mod test_insurance;
Expand All @@ -58,7 +60,7 @@
mod test_insurance_claims;
#[cfg(test)]
mod test_insurance_comprehensive;
#[cfg(test)]

Check warning on line 63 in stellar-contracts/src/lib.rs

View workflow job for this annotation

GitHub Actions / review

Diff in /home/runner/work/PetChain-Contracts/PetChain-Contracts/stellar-contracts/src/lib.rs
mod test_multisig_transfer;
#[cfg(test)]
mod test_statistics;
Expand Down Expand Up @@ -116,6 +118,25 @@
pub recorded_at: u64,
pub notes: String,
}
#[contracttype]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct BreedingRecord {
pub id: u64,
pub sire_id: u64,
pub dam_id: u64,
pub breeding_date: u64,
pub offspring_ids: Vec<u64>,
pub breeder: Address,
pub notes: String,
}
#[contracttype]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct WeightEntry {
pub pet_id: u64,
pub weight: u64,
pub recorded_at: u64,
pub recorded_by: Address,
}

#[contracttype]
#[derive(Clone, Debug, Eq, PartialEq)]
Expand Down Expand Up @@ -214,7 +235,7 @@
pub is_critical: bool,
}

// --- NUTRITION / DIET ---

Check warning on line 238 in stellar-contracts/src/lib.rs

View workflow job for this annotation

GitHub Actions / review

Diff in /home/runner/work/PetChain-Contracts/PetChain-Contracts/stellar-contracts/src/lib.rs
#[contracttype]
pub enum NutritionKey {
DietPlan(u64), // diet_id -> DietPlan
Expand Down Expand Up @@ -247,7 +268,7 @@
pub pet_id: u64,
pub weight: u32,
pub recorded_at: u64,
pub recorded_by: Address,

Check warning on line 271 in stellar-contracts/src/lib.rs

View workflow job for this annotation

GitHub Actions / review

Diff in /home/runner/work/PetChain-Contracts/PetChain-Contracts/stellar-contracts/src/lib.rs
}


Expand Down Expand Up @@ -516,7 +537,7 @@

// Vet stats and tracking
VetStats(Address),
VetPetTreated((Address, u64)), // (vet, pet_id) -> bool

Check warning on line 540 in stellar-contracts/src/lib.rs

View workflow job for this annotation

GitHub Actions / review

Diff in /home/runner/work/PetChain-Contracts/PetChain-Contracts/stellar-contracts/src/lib.rs
VetPetCount(Address), // unique pets treated

// Lab Result DataKey
Expand Down Expand Up @@ -593,7 +614,7 @@
Consent(u64),
ConsentCount,
PetConsentIndex((u64, u64)),
PetConsentCount(u64),

Check warning on line 617 in stellar-contracts/src/lib.rs

View workflow job for this annotation

GitHub Actions / review

Diff in /home/runner/work/PetChain-Contracts/PetChain-Contracts/stellar-contracts/src/lib.rs
}


Expand Down Expand Up @@ -1357,7 +1378,7 @@
species: species.clone(),
gender,
color,
weight,
weight: weight.into(),
microchip_id,
photo_hashes: Vec::new(&env),
};
Expand Down Expand Up @@ -2308,7 +2329,7 @@
.get(&NutritionKey::PetDietCount(pet_id))
.unwrap_or(0)
+ 1;
env.storage()

Check warning on line 2332 in stellar-contracts/src/lib.rs

View workflow job for this annotation

GitHub Actions / review

Diff in /home/runner/work/PetChain-Contracts/PetChain-Contracts/stellar-contracts/src/lib.rs
.instance()
.set(&NutritionKey::PetDietCount(pet_id), &pet_diet_count);
env.storage()
Expand All @@ -2317,7 +2338,7 @@

true
}

Check warning on line 2341 in stellar-contracts/src/lib.rs

View workflow job for this annotation

GitHub Actions / review

Diff in /home/runner/work/PetChain-Contracts/PetChain-Contracts/stellar-contracts/src/lib.rs
pub fn get_diet_plan(env: Env, diet_id: u64) -> Option<DietPlan> {
env.storage().instance().get(&NutritionKey::DietPlan(diet_id))
}
Expand Down Expand Up @@ -2372,7 +2393,7 @@

let entry = WeightEntry {
pet_id,
weight,
weight: weight.into(),
recorded_at: now,
recorded_by: pet.owner.clone(),
};
Expand All @@ -2391,7 +2412,7 @@
.get(&NutritionKey::PetWeightCount(pet_id))
.unwrap_or(0)
+ 1;
env.storage()

Check warning on line 2415 in stellar-contracts/src/lib.rs

View workflow job for this annotation

GitHub Actions / review

Diff in /home/runner/work/PetChain-Contracts/PetChain-Contracts/stellar-contracts/src/lib.rs
.instance()
.set(&NutritionKey::PetWeightCount(pet_id), &pet_weight_count);
env.storage()
Expand Down Expand Up @@ -2426,7 +2447,7 @@
for i in 1..=count {
if let Some(wid) = env
.storage()
.instance()

Check warning on line 2450 in stellar-contracts/src/lib.rs

View workflow job for this annotation

GitHub Actions / review

Diff in /home/runner/work/PetChain-Contracts/PetChain-Contracts/stellar-contracts/src/lib.rs
.get::<NutritionKey, u64>(&NutritionKey::PetWeightByIndex((pet_id, i)))
{
if let Some(entry) = env.storage().instance().get(&NutritionKey::WeightEntry(wid))
Expand Down Expand Up @@ -5599,124 +5620,86 @@

(total_duration, total_distance)
}

// --- GROOMING TRACKING SYSTEM ---

pub fn add_grooming_record(
// --- BREEDING RECORDS SYSTEM ---
pub fn add_breeding_record(
env: Env,
pet_id: u64,
service_type: String,
groomer: String,
cost: u64,
sire_id: u64,
dam_id: u64,
breeding_date: u64,
notes: String,
) -> u64 {
let pet: Pet = env
.storage()
.instance()
.get(&DataKey::Pet(pet_id))
.expect("Pet not found");
pet.owner.require_auth();

let count: u64 = env
.storage()
.instance()
.get(&GroomingKey::GroomingRecordCount)
.unwrap_or(0);
let sire: Pet = env.storage().instance().get(&DataKey::Pet(sire_id)).expect("Sire not found");
sire.owner.require_auth();
let count: u64 = env.storage().instance().get(&BreedingKey::BreedingRecordCount).unwrap_or(0);
let record_id = count + 1;
let date = env.ledger().timestamp();
let next_due = date + (2592000 * 2); // 60 days default

let record = GroomingRecord {
let record = BreedingRecord {
id: record_id,
pet_id,
service_type,
groomer,
date,
next_due,
cost,
sire_id,
dam_id,
breeding_date,
offspring_ids: Vec::new(&env),
breeder: sire.owner.clone(),
notes,
};

env.storage()
.instance()
.set(&GroomingKey::GroomingRecord(record_id), &record);
env.storage()
.instance()
.set(&GroomingKey::GroomingRecordCount, &record_id);

let pet_count: u64 = env
.storage()
.instance()
.get(&GroomingKey::PetGroomingCount(pet_id))
.unwrap_or(0);
let new_pet_count = pet_count + 1;
env.storage()
.instance()
.set(&GroomingKey::PetGroomingCount(pet_id), &new_pet_count);
env.storage().instance().set(
&GroomingKey::PetGroomingIndex((pet_id, new_pet_count)),
&record_id,
);

env.storage().instance().set(&BreedingKey::BreedingRecord(record_id), &record);
env.storage().instance().set(&BreedingKey::BreedingRecordCount, &record_id);
let sire_count: u64 = env.storage().instance().get(&BreedingKey::PetBreedingCount(sire_id)).unwrap_or(0);
let new_sire_count = sire_count + 1;
env.storage().instance().set(&BreedingKey::PetBreedingCount(sire_id), &new_sire_count);
env.storage().instance().set(&BreedingKey::PetBreedingIndex((sire_id, new_sire_count)), &record_id);
let dam_count: u64 = env.storage().instance().get(&BreedingKey::PetBreedingCount(dam_id)).unwrap_or(0);
let new_dam_count = dam_count + 1;
env.storage().instance().set(&BreedingKey::PetBreedingCount(dam_id), &new_dam_count);
env.storage().instance().set(&BreedingKey::PetBreedingIndex((dam_id, new_dam_count)), &record_id);
record_id
}

pub fn get_grooming_history(env: Env, pet_id: u64) -> Vec<GroomingRecord> {
let count: u64 = env
.storage()
.instance()
.get(&GroomingKey::PetGroomingCount(pet_id))
.unwrap_or(0);
pub fn get_breeding_history(env: Env, pet_id: u64) -> Vec<BreedingRecord> {
let count: u64 = env.storage().instance().get(&BreedingKey::PetBreedingCount(pet_id)).unwrap_or(0);
let mut history = Vec::new(&env);

for i in 1..=count {
if let Some(record_id) = env
.storage()
.instance()
.get::<GroomingKey, u64>(&GroomingKey::PetGroomingIndex((pet_id, i)))
{
if let Some(record) = env
.storage()
.instance()
.get::<GroomingKey, GroomingRecord>(&GroomingKey::GroomingRecord(record_id))
{
if let Some(record_id) = env.storage().instance().get::<BreedingKey, u64>(&BreedingKey::PetBreedingIndex((pet_id, i))) {
if let Some(record) = env.storage().instance().get::<BreedingKey, BreedingRecord>(&BreedingKey::BreedingRecord(record_id)) {
history.push_back(record);
}
}
}
history
}

pub fn get_next_grooming_date(env: Env, pet_id: u64) -> Option<u64> {
let history = Self::get_grooming_history(env, pet_id);
if history.is_empty() {
return None;
pub fn add_offspring(env: Env, record_id: u64, offspring_id: u64) -> bool {
if let Some(mut record) = env.storage().instance().get::<BreedingKey, BreedingRecord>(&BreedingKey::BreedingRecord(record_id)) {
record.breeder.require_auth();
record.offspring_ids.push_back(offspring_id);
env.storage().instance().set(&BreedingKey::BreedingRecord(record_id), &record);
let off_count: u64 = env.storage().instance().get(&BreedingKey::PetOffspringCount(record.sire_id)).unwrap_or(0);
let new_off_count = off_count + 1;
env.storage().instance().set(&BreedingKey::PetOffspringCount(record.sire_id), &new_off_count);
env.storage().instance().set(&BreedingKey::PetOffspringIndex((record.sire_id, new_off_count)), &offspring_id);
true
} else {
false
}
}

let mut latest_record: Option<GroomingRecord> = None;
for record in history.iter() {
match &latest_record {
Some(current) => {
if record.date > current.date {
latest_record = Some(record);
}
}
None => latest_record = Some(record),
pub fn get_offspring(env: Env, pet_id: u64) -> Vec<u64> {
let count: u64 = env.storage().instance().get(&BreedingKey::PetOffspringCount(pet_id)).unwrap_or(0);
let mut offspring = Vec::new(&env);
for i in 1..=count {
if let Some(offspring_id) = env.storage().instance().get::<BreedingKey, u64>(&BreedingKey::PetOffspringIndex((pet_id, i))) {
offspring.push_back(offspring_id);
}
}

latest_record.map(|r| r.next_due)
offspring
}

pub fn get_grooming_expenses(env: Env, pet_id: u64) -> u64 {
let history = Self::get_grooming_history(env, pet_id);
let mut total = 0u64;

pub fn get_pedigree(env: Env, pet_id: u64) -> Vec<BreedingRecord> {
let history = PetChainContract::get_breeding_history(env.clone(), pet_id);
let mut pedigree = Vec::new(&env);
for record in history.iter() {
total = total.saturating_add(record.cost);
pedigree.push_back(record);
}

total
pedigree
}
}

Expand All @@ -5736,3 +5719,4 @@
) -> Result<Bytes, ()> {
Ok(ciphertext.clone())
}

Loading