use chrono::{DateTime, FixedOffset};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::{
auth::User,
entity_ref::{ExternalId, ExternalIdEntity, Id, Ref, RefTarget, Slug, SlugEntity},
helpers::slugify,
organizations::Organization,
EntityRefPathParam, I18nString, ImageSummary, NestedSize, NestedSizeSummary, Style,
StyleSummary,
};
use samling_clorinde::{client::GenericClient, queries::color::get_color_id};
#[derive(Debug, Serialize, Deserialize, Clone, JsonSchema)]
pub struct Color {
pub id: Id<Self>,
pub style: StyleSummary,
pub number: String,
pub name: I18nString,
pub slug: Slug<Self>,
pub images: Vec<ImageSummary>,
pub external_id: Option<ExternalId<Self>>,
pub created_by: Option<Id<User>>,
pub created_at: DateTime<FixedOffset>,
pub updated_at: DateTime<FixedOffset>,
}
impl EntityRefPathParam for Color {
fn parameter_name() -> &'static str {
"color_ref"
}
}
#[derive(Debug, Serialize, Deserialize, Clone, JsonSchema)]
pub struct NestedColor {
pub id: Id<Color>,
pub number: String,
pub name: I18nString,
pub slug: Slug<Color>,
pub external_id: Option<ExternalId<Color>>,
pub images: Vec<ImageSummary>,
pub sizes: Vec<NestedSize>,
pub is_new: Option<bool>,
}
#[derive(Debug, Serialize, Deserialize, Clone, JsonSchema)]
pub struct NestedColorSummary {
pub id: Id<Color>,
pub number: String,
pub name: I18nString,
pub primary_image: Option<ImageSummary>,
pub sizes: Vec<NestedSizeSummary>,
}
impl NestedColor {
pub(crate) fn into_summary(self) -> NestedColorSummary {
NestedColorSummary {
id: self.id,
number: self.number,
name: self.name,
primary_image: self.images.into_iter().next(),
sizes: self.sizes.into_iter().map(|c| c.into_summary()).collect(),
}
}
pub(crate) fn service_item(&self) -> bool {
self.sizes
.iter()
.any(|size| size.service_item == Some(true))
}
pub(crate) fn primary_image(&self) -> Option<&ImageSummary> {
self.images.first()
}
}
#[derive(Debug, Serialize, Deserialize, Clone, JsonSchema)]
pub struct ColorSummary {
pub id: Id<Color>,
pub style: StyleSummary,
pub number: String,
pub name: I18nString,
pub slug: Slug<Color>,
pub external_id: Option<ExternalId<Color>>,
}
impl RefTarget for Color {
async fn lookup_id(
client: &impl GenericClient,
organization_id: Id<Organization>,
entity_ref: &crate::entity_ref::Ref<Self>,
) -> crate::Result<Option<Id<Self>>> {
let (id, external_id, slug) = entity_ref.to_owned().take_all_inner();
Ok(get_color_id()
.bind(
client,
&organization_id.into(),
&id,
&external_id.as_deref(),
&slug.as_deref(),
)
.opt()
.await?
.map(Id::new))
}
}
#[derive(Debug, Deserialize)]
pub struct CreateColor {
pub style: Ref<Style>,
pub number: String,
pub name: I18nString,
pub slug: Option<Slug<Color>>,
pub external_id: Option<ExternalId<Color>>,
}
impl SlugEntity for CreateColor {
type RefTarget = Color;
fn generate_slug(&self, prefix: &str) -> Option<Slug<Self::RefTarget>> {
Some(Slug::new(slugify(&[prefix, &self.number, &self.name.en])))
}
fn slug(&self) -> Option<Slug<Self::RefTarget>> {
self.slug.clone()
}
fn set_slug(&mut self, value: Slug<Self::RefTarget>) {
self.slug = Some(value);
}
}
impl ExternalIdEntity for CreateColor {
type RefTarget = Color;
fn external_id(&self) -> Option<ExternalId<Self::RefTarget>> {
self.external_id.clone()
}
fn set_external_id(&mut self, value: ExternalId<Self::RefTarget>) {
self.external_id = Some(value);
}
}
#[derive(Debug, Deserialize)]
pub struct UpdateColor {
pub style: Option<Ref<Style>>,
pub number: Option<String>,
pub name: Option<I18nString>,
pub slug: Option<Slug<Color>>,
pub external_id: Option<ExternalId<Color>>,
}
impl From<CreateColor> for UpdateColor {
fn from(color: CreateColor) -> Self {
Self {
style: Some(color.style),
number: Some(color.number),
name: Some(color.name),
slug: color.slug,
external_id: color.external_id,
}
}
}
impl SlugEntity for UpdateColor {
type RefTarget = Color;
fn slug(&self) -> Option<Slug<Self::RefTarget>> {
self.slug.clone()
}
fn set_slug(&mut self, value: Slug<Self::RefTarget>) {
self.slug = Some(value);
}
}
impl ExternalIdEntity for UpdateColor {
type RefTarget = Color;
fn external_id(&self) -> Option<ExternalId<Self::RefTarget>> {
self.external_id.clone()
}
fn set_external_id(&mut self, value: ExternalId<Self::RefTarget>) {
self.external_id = Some(value);
}
}