Ë
    §‘ˆj„  ã                   ó¦   — d Z ddlZddlZddlZddlmZmZ  ej                  e«      Z	dZ
de
z  Zdededefd	„Zdedefd
„Zddœdededee   fd„Zy)zÇFetches a Shopify catalog and maps it to SourceProduct.

Shopify's schema is fixed, so this mapping is code rather than a declarative
field map -- only heterogeneous HTTP sources need configuration.
é    N)ÚSHOPIFY_API_VERSIONÚShopQueryErroréú   a´  
query($cursor: String) {
  products(first: %d, after: $cursor) {
    nodes {
      id title handle status productType vendor tags onlineStoreUrl description
      category { fullName }
      featuredImage { url }
      collections(first: 20) { nodes { title } }
      tracksInventory
      variants(first: 100) {
        nodes {
          price compareAtPrice availableForSale
          selectedOptions { name value }
        }
      }
      metafields(first: 20) { nodes { key value } }
      complementary: metafield(
        namespace: "shopify--discovery--product_recommendation"
        key: "complementary_products"
      ) { value }
    }
    pageInfo { hasNextPage endCursor }
  }
}
ÚnodeÚshop_domainÚreturnc                 ój  — i d| j                  d«      “d| j                  d«      “d| j                  d«      “d| j                  d«      “d| j                  d«      “d| j                  d	«      “d
| j                  d«      xs i j                  d«      “d| j                  d«      xs i j                  d«      “d| j                  d«      “d| j                  d«      xs g “d| j                  d«      xs i j                  dg «      D �cg c]  }|d   ‘Œ	 c}“d| j                  d«      “d| j                  d«      “d| j                  d«      xs i j                  dg «      D ��cg c]^  }|j                  d«      |j                  d«      |j                  d«      |j                  d«      xs g D �ci c]  }|d   |d   “Œ c}dœ‘Œ` c}}“d | j                  d!«      xs i j                  dg «      D �cg c]  }|d"   |d   d#d$œ‘Œ c}“d%d&“d'|“t        | «      d d d d(œ¥S c c}w c c}w c c}}w c c}w ))NÚexternal_idÚidÚtitleÚdescriptionÚbrandÚvendorÚhandleÚproduct_urlÚonlineStoreUrlÚ	image_urlÚfeaturedImageÚurlÚraw_categoryÚcategoryÚfullNameÚproduct_typeÚproductTypeÚtagsÚcollectionsÚnodesÚstatusÚtracks_inventoryÚtracksInventoryÚvariantsÚpriceÚcompareAtPriceÚavailableForSaleÚselectedOptionsÚnameÚvalue)r"   Úcompare_at_priceÚ	availableÚoptionsÚattributes_rawÚ
metafieldsÚkeyÚ	metafield)r-   r'   ÚsourceÚsource_kindÚshopifyÚ
source_ref)Útenant_relationsÚratingÚreview_countÚfeatured_rank)ÚgetÚ_complementary)r   r   ÚcÚvÚoÚms         ú;/var/www/html/strategist-ai/app/services/catalog/shopify.pyÚto_source_productr>   ,   s’  € ð#Ø�t—x‘x “~ð#à�—‘˜'Ó"ð#ð 	�t—x‘x Ó.ð#ð 	�—‘˜(Ó#ð	#ð
 	�$—(‘(˜8Ó$ð#ð 	�t—x‘xÐ 0Ó1ð#ð 	�d—h‘h˜Ó/Ò5°2×:Ñ:¸5ÓAð#ð 	˜Ÿ™ *Ó-Ò3°×8Ñ8¸ÓDð#ð 	˜Ÿ™ Ó/ð#ð 	�—‘˜Ó Ò& Bð#ð 	ØŸ™ -Ó0Ò6°B×;Ñ;¸GÀRÓHöJ q˜˜'›
ò Jð#ð 	�$—(‘(˜8Ó$ð#ð 	˜DŸH™HÐ%6Ó7ð#ð 	ð —h‘h˜zÓ*Ò0¨b×5Ñ5°g¸rÓB÷	
ð ð Ÿ™˜w›Ø$%§E¡EÐ*:Ó$;ØŸU™UÐ#5Ó6à%&§U¡UÐ+<Ó%=Ò%CÀöEØ !ð ˜f™I q¨¡zÑ1ò Eó	ó	
ð#ð2 	à—h‘h˜|Ó,Ò2°×7Ñ7¸ÀÓDö
àð �e‘H q¨¡z¸[ÓIò
ð3#ð: 	�yð;#ð< 	�kð=#ô> +¨4Ó0ØØØòE#ð #ùòJùòEùó	
ùò
s%   ÄH Å$AH*
Æ0H%Ç H*
Ç3H0È%H*
c                 ó>  — | j                  d«      xs i j                  d«      }|si S 	 t        j                  |«      }t        |t        «      r|si S d|D �cg c]  }t        |«      ‘Œ c}iS # t        t        f$ r t
        j                  d«       i cY S w xY wc c}w )zàShopify has no native related-products field; the Search & Discovery app
    stores hand-linked products in this metafield. A merchant or app can write
    anything into it, so a malformed value is ignored rather than fatal.Úcomplementaryr'   z3Ignoring malformed complementary_products metafieldÚrelated)
r7   ÚjsonÚloadsÚ	TypeErrorÚ
ValueErrorÚloggerÚwarningÚ
isinstanceÚlistÚstr)r   ÚrawÚidsÚis       r=   r8   r8   S   s•   € ð �8‰8�OÓ$Ò*¨×
/Ñ
/°Ó
8€CÙØˆ	ðÜ�j‰j˜‹oˆô �cœ4Ô ©Øˆ	Ø¨Ö, 1œ˜A�Ò,Ð-Ð-øô ”zÐ"ò Ü�‰ÐLÔMØŠ	ðüò
 -s   ªA. ÁBÁ.&BÂB)ÚclientÚshopÚtokenc             ƒ   óÄ  K  — |du }|xs t        j                  d¬«      }g d}}	 	 |j                  d| › dt        › d�|ddœt        d	|id
œ¬«      ƒ d{  –—† }|j
                  dk7  r9t        j                  d| |j
                  «       t        d|j
                  › �«      ‚|j                  «       }|j                  d«      r-t        j                  d| «       t        t        |d   «      «      ‚|d   d   }	|j                  |	d   «       |	d   d   s||r|j                  «       ƒ d{  –—†  S S |	d   d   }�Œ7 Œå7 Œ# |r|j                  «       ƒ d{  –—†7   w w xY w­w)zŽEvery page or nothing: a partial fetch must not be mistaken for a
    complete catalog, or the sync would delete products it simply never saw.Ng      N@)Útimeoutzhttps://z/admin/api/z/graphql.jsonzapplication/json)zX-Shopify-Access-TokenzContent-TypeÚcursor)ÚqueryÚ	variables)ÚheadersrB   éÈ   z$Catalog fetch for %s failed: HTTP %szHTTP Úerrorsz,Catalog fetch for %s returned GraphQL errorsÚdataÚproductsr   ÚpageInfoÚhasNextPageÚ	endCursor)ÚhttpxÚAsyncClientÚpostr   ÚPRODUCTS_QUERYÚstatus_coderF   Úerrorr   rB   r7   rJ   ÚextendÚaclose)
rO   rP   rN   Úownedr9   r   rS   ÚrespÚbodyÚpages
             r=   Úfetch_productsrj   d   sz  è ø€ ð �dˆN€EØÒ1”%×#Ñ#¨DÔ1€AØ˜ˆ6€EðØØŸ™Ø˜4˜& Ô,?Ð+@ÀÐNØ38Ø);ñ=ä-¸XÀvÐ<NÑOð	  ó ÷ ˆDð ×Ñ 3Ò&Ü—‘ÐCØ! 4×#3Ñ#3ô5ä$ u¨T×-=Ñ-=Ð,>Ð%?Ó@Ð@à—9‘9“;ˆDØ�x‰x˜Ô!Ü—‘ÐKÈTÔRÜ$¤S¨¨h©Ó%8Ó9Ð9à˜‘< 
Ñ+ˆDØ�L‰L˜˜g™Ô'Ø˜
Ñ# MÒ2Øñ Ø—(‘(“*×Ñð ð ˜*Ñ% kÑ2ˆFñ+ ðøð. ùñ Ø—(‘(“*×Òð üsM   ‚#E ¦/D? ÁD;ÁB?D? ÄE Ä*D=Ä+E Ä1D? Ä=E Ä?EÅEÅEÅE )Ú__doc__rB   Úloggingr^   Ú'app.services.integrations.shopify_oauthr   r   Ú	getLoggerÚ__name__rF   Ú	PAGE_SIZEra   ÚdictrJ   r>   r8   rI   rj   © ó    r=   ú<module>rt      s‘   ðñó
 Û ã ç Wà	ˆ×	Ñ	˜8Ó	$€à€	ðð0 ñ1€ð6$˜Dð $¨sð $°tó $ðN.˜ð . $ó .ð" ;?ò ˜sð ¨3ð À4ÈÁ:ô rs   