o
    -h                     @   s   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mZ d d
lZeeZG dd dejZG dd dejZG dd dejZd
S )    )models)settings)ValidationError)transaction)Decimal)timezone)now)Customer)ProductBatchNc                       s*  e Zd Zg dZejeddejdZej	ddddZ
ejdedZejedd	Zejd
dZejejejdZej	dddddZej	dddddZej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ZejdddZejd
dZG dd dZdd Z dd Z! fddZ"e#dd Z$  Z%S )Sale)cashCash)mpesazM-Pesa)creditCredit)chequeChequeT)nullblank	on_delete
      r   )
max_digitsdecimal_placesdefault
max_lengthchoices)r   db_indexFr   r   )r   r   r   r      r   r   r   r   r   2   c                   @      e Zd ZdgZdS )z	Sale.Metaz
-sale_dateN__name__
__module____qualname__ordering r-   r-   !/var/www/html/pos/sales/models.pyMeta1       
r/   c                 C   s   d| j  d| j d| j dS )NSale # - z ())idtotal_amountpayment_methodselfr-   r-   r.   __str__4   s   zSale.__str__c              	   C   s  | j dkr| jstd| j dkr| jstd| j dkr&| jdu r&td| j dkr| js2td	| js9td
| jra| jratj	j
| j| jddj| jrP| jndd}| ratd| j d| jr| jt  k rtd| j d| j d| j d dS dS dS dS )z&Validation for payment-specific fieldsr   z0Cash amount given is required for cash payments.r   zM-Pesa reference is required.r   Nz7Credit amount must be specified (use 0 for no deposit).r   zCheque number is required.zCheque date is required.)customercheque_numberr6   )r4   zCheque number z" already exists for this customer.zPast-dated cheque recorded: #z (Date: z
, Amount: r3   )r6   
cash_givenr   mpesa_referencecredit_amountr;   cheque_dater:   r   objectsfilterexcluder4   existsr   r   dateloggerwarningr5   )r8   existing_chequer-   r-   r.   clean7   s@   



z
Sale.cleanc                    sZ   |    | jdkr| jr| j| j | _| jdk| _n| jdv r"d| _t j|i | dS )zHandle payment completion logicr   r   )r   r   TN)
full_cleanr6   r<   r5   
change_dueis_completesupersaver8   argskwargs	__class__r-   r.   rM   [   s   
z	Sale.savec                 C   s,   | j dkrt| j| jpd tdS tdS )z/Calculate remaining credit for partial paymentsr   r   )r6   maxr5   r>   r   r7   r-   r-   r.   outstanding_creditj   s   
zSale.outstanding_credit)&r)   r*   r+   PAYMENT_METHOD_CHOICESr   
ForeignKeyr	   SET_NULLr:   DecimalFieldr5   	CharFieldr6   DateTimeFieldr   	sale_dateBooleanFieldrK   r   AUTH_USER_MODELCASCADEuserr<   rJ   r=   r>   	DateFieldcredit_paid_dater;   r?   cheque_clearedr/   r9   rH   rM   propertyrT   __classcell__r-   r-   rQ   r.   r      s,    
$r   c                       s   e Zd ZejedejdZejeej	dZ
ejeej	dddZe ZejdddZejddd	d
Zdd Z fddZ  ZS )SaleItemitemsrelated_namer   r"   T)r   r   r   r   r   r   r   F)r   r   editablec                 C   s`   | j r| j| j jkrtd| j j d| j j | j s,| j| jjkr.td| jj ddS dS )zValidate stock availabilityzOnly z units available in batch z units availableN)batchquantityr   
batch_codeproductstock_quantityr7   r-   r-   r.   rH   {   s
   zSaleItem.cleanc                    sB   | j s| jr
| jj n| jj | _ | j | j | _t j|i | dS )z&Auto-calculate prices and update stockN)selling_pricerk   rn   rl   subtotalrL   rM   rN   rQ   r-   r.   rM      s   zSaleItem.save)r)   r*   r+   r   rV   r   r^   saler
   PROTECTrn   r   rk   PositiveIntegerFieldrl   rX   rp   rq   rH   rM   rd   r-   r-   rQ   r.   re   r   s    re   c                   @   s   e Zd ZdZg dZejedejdZ	ej
dedZejdddZej
d	d
d
dZej
dd
d
dZejd
d
dZejedZG dd dZdd ZdS )SalePaymentz0Track multiple payment methods for a single saler   paymentsrg   r   r   r   ri   r#   Tr$   r&   r%   r!   c                   @   r'   )zSalePayment.Metaz-created_atNr(   r-   r-   r-   r.   r/      r0   r/   c                 C   s    d| j j d|   d| j S )Nr1   r2   z - KSh )rr   r4   get_payment_method_displayamountr7   r-   r-   r.   r9      s    zSalePayment.__str__N)r)   r*   r+   __doc__rU   r   rV   r   r^   rr   rY   r6   rX   rx   r=   r;   r`   r?   rZ   r   
created_atr/   r9   r-   r-   r-   r.   ru      s    ru   )	django.dbr   django.confr   django.core.exceptionsr   r   decimalr   django.utilsr   django.utils.timezoner   customers.modelsr	   inventory.modelsr
   r   logging	getLoggerr)   rE   Modelr   re   ru   r-   r-   r-   r.   <module>   s    
a