o
    qvh$                     @   s   d dl mZ d dlZd dlZd dlmZ d dlmZ d dlm	Z	 d dl
mZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZ G dd dejZG dd dejZG dd dejZG dd dejZG dd dejZdS )    )appsN)	timedelta)uuid4)ProcessedImageField)ResizeToFill)models)ValidationError)slugify)now)Supplierc                       s   e Zd Z fddZ  ZS )ActiveManagerc                    s   t   jddS )NT)deleted_at__isnull)superget_querysetfilterself	__class__ ,/var/www/html/hyperkenya/inventory/models.pyr      s   zActiveManager.get_queryset)__name__
__module____qualname__r   __classcell__r   r   r   r   r      s    r   c                       s   e Zd ZejdddZejdddddZejdddZ	ej
ddddZejdddd	ejd
ZejdddZ fddZdd Z  ZS )Category   T)
max_lengthunique)r   r   blanknullr   r    zcategory_images/	upload_tor   r    r   subcategories)r    r   related_name	on_deleter    r   c                    s(   | j s	t| j| _ t j|i | d S N)slugr	   namer   saver   argskwargsr   r   r   r+      s   zCategory.savec                 C   s   | j S r(   )r*   r   r   r   r   __str__$   s   zCategory.__str__)r   r   r   r   	CharFieldr*   	SlugFieldr)   	TextFielddescription
ImageField	thumbnail
ForeignKeyCASCADEparentDateTimeField
deleted_atr+   r/   r   r   r   r   r   r      s    r   c                       s  e Zd ZejddZejddddZejdddZejddddddZ	ej
ddddd	Zej
ddd
Zej
ddddd	ZejddZejddZejddddZejdddZejddZejdddejdddZejdddZejddddZejdddZej
ddddd	ZejdddZ ejdddZ!ejddddZ"ejdddZ#e$ Z%e& Z'dd Z(dd Z) fddZ*e+dd  Z,d!d" Z-d#d$ Z.d%d& Z/d'd( Z0d)d* Z1G d+d, d,Z2  Z3S )-Productr   )r   Tr   r   r    )r   r   )r   r   r    r   db_index
      
max_digitsdecimal_placesr   r    rA   rB   r   default2   r!   auto_now_addr   products)r    r   r&   r=   r%   product_images/r"   F)rE   r=   r'   F   c                 C   s    | j r| j d| j  dS | jS )Nz ())variantr*   r   r   r   r   r/   F   s    zProduct.__str__c                 C   s`   | j dur| j| j krtd| jr| j| jkrtd| jdk r%td| jdk r.tddS )z6
        Validation logic for product fields.
        N0Selling price must be greater than buying price.z3Discount price must be less than the selling price.r   z"Stock quantity cannot be negative.z'Low stock threshold cannot be negative.)buying_priceselling_pricer   discount_pricestock_quantitylow_stock_thresholdr   r   r   r   cleanI   s   

zProduct.cleanc                    s   | j s8t| jr| j d| j n| j}|}d}tjj|d r5| d| }|d7 }tjj|d s!|| _ | js@| 	 | _| 
  t j|i | dS )zM
        Override save method to handle slug and barcode generation.
        -   )r)   N)r)   r	   rM   r*   r;   objectsr   existsbarcodegenerate_barcoderT   r   r+   )r   r-   r.   	base_slugunique_slugcounterr   r   r   r+   V   s   "
zProduct.savec                   C   s   d tjtjddS )z6
        Generates a random 12-digit barcode.
            )k)joinrandomchoicesstringdigitsr   r   r   r   rZ   l   s   zProduct.generate_barcodec                 O   s   t  | _|   dS )z[
        Soft-delete the product by setting `deleted_at` to the current timestamp.
        N)r
   r:   r+   r,   r   r   r   deletes   s   zProduct.deletec                 C   s   d| _ |   dS )zT
        Restore a soft-deleted product by clearing the `deleted_at` field.
        N)r:   r+   r   r   r   r   restorez   s   zProduct.restorec                 C   s   | j | jkS )zN
        Check if the product stock is below the low stock threshold.
        )rR   rS   r   r   r   r   is_low_stock   s   zProduct.is_low_stockc                 C   s$   | j rt  | j tdd kS dS )zH
        Check if the product is nearing expiry within 30 days.
           )daysF)expiry_dater
   dater   r   r   r   r   is_nearing_expiry   s   zProduct.is_nearing_expiryc                 C   s   | j rt  | j kS dS )z3
        Check if the product has expired.
        F)rk   r
   rl   r   r   r   r   has_expired   s   zProduct.has_expiredc                   @   s   e Zd ZddgZdS )zProduct.Metar*   rM   N)r   r   r   unique_togetherr   r   r   r   Meta   s    rp   )4r   r   r   r   r0   r*   rM   r1   r)   rY   DecimalFieldrO   rP   wholesale_pricePositiveIntegerFieldrR   rS   packaging_type	DateFieldrk   r9   
created_atr6   SET_NULLcategoryr2   r3   r4   imageBooleanFieldis_featuredrQ   	is_activer:   	seo_titleseo_descriptionr   rW   Managerall_objectsr/   rT   r+   staticmethodrZ   rf   rg   rh   rm   rn   rp   r   r   r   r   r   r;   )   sF    
r;   c                   @   s   e Zd ZejedejdZede	ddgdddidZ
ed	e	d
d
gdddidddZejddZejddddZejddZejddddZdd Zdd ZG dd dZdS )ProductImageimagesr%   r&   rJ   i   JPEGqualityU   )r#   
processorsformatoptionszproduct_thumbnails/   T)r#   r   r   r   r   r    FrD   r   r<   r   c                 C   s*   | j r| jjjdd rtdd S d S )NT)
is_primaryz.Only one primary image is allowed per product.)r   productr   r   rX   r   r   r   r   r   rT      s   zProductImage.cleanc                 C   s   d| j j S )Nz
Image for )r   r*   r   r   r   r   r/      s   zProductImage.__str__c                   @      e Zd ZdgZdS )zProductImage.MetaorderNr   r   r   orderingr   r   r   r   rp          
rp   N)r   r   r   r   r6   r;   r7   r   r   r   ry   r5   rz   r   r0   alt_textrs   r   captionrT   r/   rp   r   r   r   r   r      s.    

r   c                       s  e Zd Zg dZejddejdZejddddZ	e
 Zejdd	d
Zejdd	dddZejdddZejddZejdddZejedZejdeddZejdddZejeejdddZe Ze Zdd Z  fddZ!e"dd Z#dd Z$G dd dZ%  Z&S )Batch))activeActive)expiredExpired)sold_outzSold Outr;   batchesr   r   Tr<   r>   r?   rC   r@   r!   rG   r'   rD      r   )r   rc   rE   )r&   r    r   c                 C   sR   | j r| j t  k rtd| jdk rtd| jr%| j| jkr'tddS dS )z<
        Validation logic to ensure data integrity.
        z"Expiry date cannot be in the past.r   z"Batch quantity cannot be negative.rN   N)rk   r
   rl   r   quantityrP   rO   r   r   r   r   rT      s   
zBatch.cleanc                    s2   | j s|  | _ tdd}t j|i | dS )zG
        Override save to generate batch code if not provided.
        	suppliersr   N)
batch_codegenerate_batch_coder   	get_modelr   r+   )r   r-   r.   r   r   r   r   r+      s   
z
Batch.savec                   C   s   dt  jdd   S )z0
        Generates a unique batch code.
        zBATCH-N   )r   hexupperr   r   r   r   r      s   zBatch.generate_batch_codec                 C   s   d| j  d| jj S )NzBatch z for )r   r   r*   r   r   r   r   r/      s   zBatch.__str__c                   @   r   )z
Batch.Metareceived_dateNr   r   r   r   r   rp      r   rp   )'r   r   r   STATUS_CHOICESr   r6   r7   r   r0   r   rs   r   rq   rO   rP   ru   rk   r9   rv   r:   r
   r   statusr2   notesr   rw   supplierr   rW   r   r   rT   r+   r   r   r/   rp   r   r   r   r   r   r      s,    
r   )django.appsr   rb   rd   datetimer   uuidr   imagekit.modelsr   imagekit.processorsr   	django.dbr   django.core.exceptionsr   django.utils.textr	   django.utils.timezoner
   suppliers.modelsr   r   r   Modelr   r;   r   r   r   r   r   r   <module>   s"    s!