diff --git a/src/models/company_info.rs b/src/models/company_info.rs index 2d6da7a..f45dd98 100644 --- a/src/models/company_info.rs +++ b/src/models/company_info.rs @@ -1,7 +1,9 @@ use chrono::NaiveDateTime; use serde_derive::{Deserialize, Serialize}; +use diesel::prelude::*; use crate::schema::company_infos; +use crate::DbConn; /// The company (information) model. /// @@ -57,6 +59,21 @@ pub struct CompanyInfo { pub updated_at: NaiveDateTime, } +impl CompanyInfo { + /// Returns the original/previous company information model (if any). + pub fn original(&self, conn: &DbConn) -> QueryResult> { + use diesel::associations::HasTable; + + match self.original_id { + Some(original_id) => CompanyInfo::table() + .find(original_id) + .first(&**conn) + .optional(), + None => Ok(None), + } + } +} + /// The new company (information) model. /// /// This model represents new company information that can be inserted into the database. diff --git a/src/models/customer.rs b/src/models/customer.rs index eaa0fd2..ef57f8c 100644 --- a/src/models/customer.rs +++ b/src/models/customer.rs @@ -1,7 +1,10 @@ use chrono::NaiveDateTime; use serde_derive::{Deserialize, Serialize}; +use diesel::prelude::*; +use crate::models::{Invoice, Task}; use crate::schema::customers; +use crate::DbConn; /// The customer model. /// @@ -38,6 +41,31 @@ pub struct Customer { pub updated_at: NaiveDateTime, } +impl Customer { + /// Returns the invoices billed to the customer. + pub fn invoices(&self, conn: &DbConn) -> QueryResult> { + Invoice::belonging_to(self).load(&**conn) + } + + /// Returns the project/tasks associated with the customer. + pub fn tasks(&self, conn: &DbConn) -> QueryResult> { + Task::belonging_to(self).load(&**conn) + } +} + +#[object(Context = DbConn)] +impl Customer { + /// Returns the invoices billed to the customer. + fn invoices(&self, context: &DbConn) -> FieldResult> { + self.invoices(context).map_err(Into::into) + } + + /// Returns the project/tasks associated with the customer. + fn tasks(&self, context: &DbConn) -> FieldResult> { + self.tasks(context).map_err(Into::into) + } +} + /// The new customer model /// /// This model represents a new customer that can be inserted into the database. diff --git a/src/models/invoice.rs b/src/models/invoice.rs index 7915d75..1fd39da 100644 --- a/src/models/invoice.rs +++ b/src/models/invoice.rs @@ -1,8 +1,10 @@ use chrono::NaiveDateTime; use serde_derive::{Deserialize, Serialize}; +use diesel::prelude::*; -use crate::models::{CompanyInfo, Customer}; +use crate::models::{CompanyInfo, Customer, Task}; use crate::schema::invoices; +use crate::DbConn; /// The invoice model. /// @@ -31,6 +33,29 @@ pub struct Invoice { pub updated_at: NaiveDateTime, } +impl Invoice { + /// Returns the associated company info at the time of billing. + pub fn company_info(&self, conn: &DbConn) -> QueryResult { + use diesel::associations::HasTable; + + CompanyInfo::table() + .find(self.company_info_id) + .first(&**conn) + } + + /// Returns the associated customer. + pub fn customer(&self, conn: &DbConn) -> QueryResult { + use diesel::associations::HasTable; + + Customer::table().find(self.customer_id).first(&**conn) + } + + /// Returns the billed tasks included in the invoice. + pub fn tasks(&self, conn: &DbConn) -> QueryResult> { + Task::belonging_to(self).load(&**conn) + } +} + /// The new invoice model. /// /// This model represents an new invoice for a customer that can be inserted into the database. diff --git a/src/models/task.rs b/src/models/task.rs index 487c339..e55fcc9 100644 --- a/src/models/task.rs +++ b/src/models/task.rs @@ -1,8 +1,10 @@ use chrono::NaiveDateTime; use serde_derive::{Deserialize, Serialize}; +use diesel::prelude::*; -use crate::models::{Customer, Invoice}; +use crate::models::{Customer, Invoice, TimeEntry}; use crate::schema::tasks; +use crate::DbConn; /// The task (or project) model. /// @@ -35,6 +37,30 @@ pub struct Task { pub updated_at: NaiveDateTime, } +impl Task { + /// Returns the associated customer. + pub fn customer(&self, conn: &DbConn) -> QueryResult { + use diesel::associations::HasTable; + + Customer::table().find(self.customer_id).first(&**conn) + } + + /// Returns the associated invoice (if billed) + pub fn invoice(&self, conn: &DbConn) -> QueryResult> { + use diesel::associations::HasTable; + + match self.invoice_id { + Some(invoice_id) => Invoice::table().find(invoice_id).first(&**conn).optional(), + None => Ok(None), + } + } + + /// Returns the registered time entries. + pub fn time_entries(&self, conn: &DbConn) -> QueryResult> { + TimeEntry::belonging_to(self).load(&**conn) + } +} + /// The new task model. /// /// This model represents a new task (or project) of a customer that can be inserted into the diff --git a/src/models/time_entry.rs b/src/models/time_entry.rs index a00b8bd..1cbf767 100644 --- a/src/models/time_entry.rs +++ b/src/models/time_entry.rs @@ -1,8 +1,10 @@ use chrono::NaiveDateTime; use serde_derive::{Deserialize, Serialize}; +use diesel::prelude::*; use crate::models::Task; use crate::schema::time_entries; +use crate::DbConn; /// The time entry model. /// @@ -29,6 +31,15 @@ pub struct TimeEntry { pub updated_at: NaiveDateTime, } +impl TimeEntry { + /// Returns the task the entry is registered for. + pub fn customer(&self, conn: &DbConn) -> QueryResult { + use diesel::associations::HasTable; + + Task::table().find(self.task_id).first(&**conn) + } +} + /// The new time entry model. /// /// This model represents a new registered amount of time that can be inserted into the database.