
    `j!                         d dl Z d dlmZ ddlmZ defdZ G d dej                        Z G d	 d
ej                        Z	y)    N)models   )ISTAT_GUEST_TYPE_CHOICESreturnc                  >    t        j                         j                  S )zGenerate a permanent regulatory identity token.

    Returns a 32-character hex string derived from a random UUID v4.
    This function is the ONLY authorised source of idswh values.
    It must never be called outside of GuestStay.save().
    )uuiduuid4hex     /backend/guests/models.pygenerate_idswhr   	   s     ::<r   c                       e Zd ZdZ ej
                  dej                  dd      Z ej
                  dej                  dd      Z ej                  d	
      Z
 ej                  d
      Z ej                  dddddd      Z ej                  d      Z ej                  d      Z G d d      ZdefdZd fdZ xZS )	GuestStayuP  Canonical regulatory identity root for a single guest stay.

    This model is the ONLY source of truth for cross-system identity.
    It represents one physical guest stay (check-in → check-out lifecycle)
    and one regulatory reporting unit across all export systems:
    C59 / ISTAT / Ross 1000 / Alloggiati Web.

    Identity rules (NON-NEGOTIABLE):
    - ``idswh`` is generated once at creation and never recomputed.
    - No external system, serializer, or export layer may set or mutate it.
    - Re-exporting old data must always read the stored value, never derive a new one.
    bookings.Bookingguest_staysz!The booking this stay belongs to.)	on_deleterelated_name	help_textzguests.GueststayszThe guest this stay belongs to.z7Check-in date copied from the booking at creation time.)r   z8Check-out date copied from the booking at creation time.@   TFzPermanent, globally unique regulatory identity token. Generated once at creation. Never recomputed, never overwritten. Used as the canonical identifier across C59, ISTAT, Ross 1000, and Alloggiati Web exports.)
max_lengthuniqueeditablenulldb_indexr   auto_now_addauto_nowc                   h    e Zd ZdZ ej
                  ddgd       ej
                  ddgd      gZy	)
GuestStay.Metar   bookingguestgueststay_booking_guest_idx)fieldsnamecheck_in_datecheck_out_dategueststay_dates_idxN)__name__
__module____qualname__db_tabler   Indexindexesr   r   r   Metar"   J   s;     FLLG 4;XYFLL2B CJ_`
r   r1   r   c                 V    d| j                    d| j                   d| j                   dS )NzGuestStay(id=z, idswh=z, guest_id=))pkidswhguest_idselfs    r   __str__zGuestStay.__str__Q   s*    twwix

|;t}}oUVWWr   c                 Z    | j                   st               | _         t        |   |i | y)a[  Assign idswh exactly once at creation.

        The guard ``if not self.idswh`` ensures:
        - New records receive a fresh token automatically.
        - Existing records (updates) are never touched.
        - No external caller can inject or overwrite the value because
          ``editable=False`` blocks form/serializer assignment.
        N)r5   r   supersave)r8   argskwargs	__class__s      r   r<   zGuestStay.saveT   s'     zz')DJd%f%r   )r   N)r+   r,   r-   __doc__r   
ForeignKeyCASCADEr#   r$   	DateFieldr(   r)   	CharFieldr5   DateTimeField
created_at
updated_atr1   strr9   r<   __classcell__r?   s   @r   r   r      s      f.."5	G F..3	E %F$$KM &V%%LN
 F*E &%%48J%%%t4J
 
X X& &r   r   c                   h    e Zd Zg dZg dZ ej                  dej                  ddd      Z ej                  d	      Z
 ej                  d
      Z ej                  ddded      Z ej                  dd      Z ej                  ddd      Z ej$                  dd      Z ej                  ddd      Z ej                  ddd      Z ej                  ddd      Z ej                  dedd      Z ej                  dddd      Z ej                  dddd      Z ej                  dedd      Z ej                  ddd      Z ej$                  dd      Z ej$                  dd      Z ej                  ddd      Z ej                  ddd      Z ej                  ddd      Z  ej                  ddd      Z! ej                  ddd      Z" ej                  ddd      Z# ejH                  dd      Z% ejH                  dd      Z& ejN                  dde(d      Z) ejT                  d      Z+ ejT                  d      Z, ej                  dd      Z- ej                  dddd      Z. ejH                  ddd !      Z/ G d" d#      Z0d$ Z1 fd%Z2 xZ3S )&Guest))maleMale)femaleFemale)otherOther))passportPassport)id_cardzID Card)drivers_licensezDriver's Licenser   guestsTF)r   r   r   blank   )r   )default   z,ISTAT lodging type code for the guest record)r   rX   r   choicesr   )rX   r      )r   rX   r   d   )r   r\   rX   r   r   z,ISTAT tourism type associated with the guest)r   rX   r   r   z.ISTAT transport type associated with the guest2   zTStore template-driven additional/custom fields for this guest (keyed by field slug).)rX   r   rZ   r   r   r   z,If true, guest is fully exempt from city tax)rZ   r   z7Reason for exemption (Medical, Student, Resident, etc.))r   r   rX   r   z(Internal notes for audit or verification)r   rX   r   c                       e Zd ZdZdgZy)
Guest.MetarW   z-created_atN)r+   r,   r-   r.   orderingr   r   r   r1   ra      s    !?r   r1   c                 H    | j                    d| j                  rd dS d dS )Nz - Main
Additionalz Guest)	full_nameis_main_guestr7   s    r   r9   zGuest.__str__   s2    ..!t/A/AV$TTZ[[|$TTZ[[r   c                     ddl m}  ||        |j                  d      }|t        |      j	                  h d      |d<   t        |   |i | y )Nr   )apply_istat_guest_defaultsupdate_fields>   countrynationalitytourism_typetransport_typecountry_of_birth)guests.guest_defaultsri   getsetunionr;   r<   )r8   r=   r>   ri   rj   r?   s        r   r<   z
Guest.save   sT    D"4(

?3$&)-&8&>&>'F?# 	d%f%r   )4r+   r,   r-   GENDER_CHOICESDOCUMENT_TYPE_CHOICESr   rA   rB   r#   rD   rf   BooleanFieldrg   r   
guest_type
EmailFieldemailphonerC   date_of_birthro   cityregiongenderrm   rn   document_type	id_numberdocument_issue_datedocument_expiry_datedocument_issuing_countryrl   addresszip_coderk   language_preference	TextFieldspecial_requestsguest_notes	JSONFielddict
extra_datarE   rF   rG   is_city_tax_exemptcity_tax_exemption_reasoncity_tax_exemption_notesr1   r9   r<   rI   rJ   s   @r   rL   rL   a   s%   N  f..G !  C0I'F''6M!!!(@J FDt4EF$TBE %F$$4d;M'v''3dN6s$TBDVDtDFV^4VZ[F#6##@	L &V%%B	N %F$$<QY]dhiM   BdFI*&**DA+6++$TB/v//3dQUV #&""cDIKf#TEGv2TEHf#TEG +&**b4P'v''d>"&""D9K!!!h	J &%%48J%%%t4J -,,@
 !1 0 0K	!  0v//< # #\& &r   rL   )
r   	django.dbr   istat_utilsr   rH   r   Modelr   rL   r   r   r   <module>r      s?      1 L& L&\}&FLL }&r   