1use crate::dto;
2use domain::retail;
3
4use super::{Error, ProviderField, Result};
5
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct ProductCandidate {
9 pub provider_item_id: dto::retail::ItemId,
11 pub name: retail::product::Name,
13 pub product: retail::Product,
15 pub status: retail::OfferingStatus,
17}
18
19pub fn product_candidate(item: &dto::retail::Item) -> Result<ProductCandidate> {
21 let name = item
22 .name
23 .as_deref()
24 .ok_or(Error::MissingRequiredProviderField {
25 field: ProviderField::RetailItemName,
26 })?;
27 let name = retail::product::Name::try_new(name).map_err(|err| Error::InvalidDomainValue {
28 field: ProviderField::RetailItemName,
29 reason: err.to_string(),
30 })?;
31
32 let sku = item
33 .sku
34 .as_deref()
35 .ok_or(Error::MissingRequiredProviderField {
36 field: ProviderField::RetailItemSku,
37 })?;
38 let sku = retail::Sku::try_new(sku).map_err(|err| Error::InvalidDomainValue {
39 field: ProviderField::RetailItemSku,
40 reason: err.to_string(),
41 })?;
42
43 let category = item
44 .category
45 .as_deref()
46 .map(promote_category)
47 .transpose()?
48 .unwrap_or(retail::product::Category::PersonalizedUpsell);
49 let status = if item.active.unwrap_or(true) {
50 retail::OfferingStatus::Active
51 } else {
52 retail::OfferingStatus::Inactive
53 };
54
55 Ok(ProductCandidate {
56 provider_item_id: item.id,
57 name,
58 product: retail::Product::new(sku, category),
59 status,
60 })
61}
62
63fn promote_category(value: &str) -> Result<retail::product::Category> {
64 match value.trim().to_ascii_lowercase().as_str() {
65 "supplement" | "supplements" => Ok(retail::product::Category::Supplement),
66 "in_house_diet" | "in-house diet" | "in house diet" | "food" | "diet" => {
67 Ok(retail::product::Category::InHouseDiet)
68 }
69 "personalized_upsell" | "personalized upsell" | "upsell" | "retail" => {
70 Ok(retail::product::Category::PersonalizedUpsell)
71 }
72 _ => Err(Error::InvalidDomainValue {
73 field: ProviderField::RetailItemCategory,
74 reason: format!("unsupported Gingr retail category {value:?}"),
75 }),
76 }
77}