use chrono::NaiveDateTime;
use serde_derive::{Deserialize, Serialize};

use crate::models::{Customer, Invoice};
use crate::schema::tasks;

/// The task (or project) model.
///
/// This model represents a task (or project) of a customer on which time can be registered.
/// generated.
#[derive(AsChangeset, Associations, Debug, Deserialize, Identifiable, Queryable, Serialize)]
#[belongs_to(Customer)]
#[belongs_to(Invoice)]
#[table_name = "tasks"]
pub struct Task {
    /// The unique identification number
    pub id: i32,
    /// The ID of the associated customer
    pub customer_id: i32,
    /// The fixed cost of the task (if applicable)
    pub fixed_cost: Option<f32>,
    /// The hourly rate of the task (if applicable)
    pub hourly_rate: Option<f32>,
    /// An extra comment for on the invoice
    pub invoice_comment: String,
    /// The associated invoice (if billed)
    pub invoice_id: Option<i32>,
    /// The name/description
    pub name: String,
    /// The VAT rate (at time of billing)
    pub vat_rate: f32,
    /// The time of creation
    pub created_at: NaiveDateTime,
    /// The time of last update
    pub updated_at: NaiveDateTime,
}

/// The new task model.
///
/// This model represents a new task (or project) of a customer that can be inserted into the
/// database.
#[derive(Debug, Deserialize, Insertable, Serialize)]
#[table_name = "tasks"]
pub struct NewTask {
    /// The ID of the associated customer
    pub customer_id: i32,
    /// The fixed cost of the task (if applicable)
    pub fixed_cost: Option<f32>,
    /// The hourly rate of the task (if applicable)
    pub hourly_rate: Option<f32>,
    /// An extra comment for on the invoice
    pub invoice_comment: String,
    /// The associated invoice (if billed)
    pub invoice_id: Option<i32>,
    /// The name/description
    pub name: String,
    /// The VAT rate (at time of billing)
    pub vat_rate: f32,
}
