return

mail@pastecode.io avatar
unknown
python
2 years ago
6.7 kB
3
Indexable
Never

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def serial_number_verfication(request):
    invoice_no = request.kwargs.get('invoice_no')
    supplier_slug = request.kwargs.get('supplier_slug')
    barcode =  request.kwargs.get('serial_no')
    purchase_order = PurchaseOrder(invoice_no = invoice_no, supplier__slug = supplier_slug)
    if  ProductSerial.objects.filter(barcode = barcode, purchase_order_item__purchase_order = purchase_order).exists():
        return Response(data={'message':True}) 
    return Response(data={'message':False}) 


class AdminPurchaseOrderReturnListCreateAPIView(ListCreateAPIView):
    permission_classes = (IsAuthenticated, (IsStaff | IsSuperUser),)
    serializer_class = PurchaseOrderReturnSerializer
    queryset = PurchaseOrderReturn.objects.all()

    def create(self, request, *args, **kwargs):
        self.cache_common_data()
        if self.supplier != self.purchase_order.supplier:
            return Response({'message' : 'Supplier & PurchaseOrder mismatch'}, status=status.HTTP_409_CONFLICT)
        if self.check_product_serial_and_product_variant_mismatch_and_product_not_returned():
            return Response({'message' : 'Product & ProductVariant mismatch or product not in the stock'}, status=status.HTTP_409_CONFLICT)

        with transaction.atomic():
            self.purchase_order_return, purchase_order_return_serializer = self.create_purchase_order_return()
            purchase_order_return_items = self.create_purchase_order_return_items(self.purchase_order_return)
            self.update_product_serial_objects()
            for item in purchase_order_return_items:
                product_variant = item.product_variant
                purchase_order_item = item.purchase_order_item
                stock = Stock.objects.get(product_variant = product_variant, store = self.store)
                StockHistory.objects.create(
                    type=TransactionTypes.PURCHASE_RETURN,
                    store= self.store,
                    stock = stock,
                    product_variant= product_variant ,
                    invoice_no=purchase_order_item.purchase_order.invoice_no,
                    quantity=stock.quantity,
                    balance=stock.quantity,
                    created_by=request.user)
                stock.quantity -= item.quantity
                stock.save()    
        return Response(purchase_order_return_serializer.data, status=status.HTTP_201_CREATED)

    def  cache_common_data(self):
        self.purchase_order = PurchaseOrder.objects.get(id = self.request.data['purchase_order'])
        self.supplier = Supplier.objects.get(id =self.request.data['supplier'])
        self.return_items = self.get_return_item_data()
        self.total_return_amount = sum([item['total_price'] for item in self.return_items])
        self.store = Store.objects.get(id = self.request.data['store'])

    
    def get_return_item_data(self):
        return_items = self.request.data.get('purchase_order_return_items')
        return_items = self.remove_duplicate_product_variant_items(return_items)
        for item in return_items:   
            serial_numbers = item['serial_numbers']
            quantity = len(serial_numbers)
            product_variant = ProductVariant.objects.get(id = item['product_variant'])
            purchase_order_item = PurchaseOrderItem.objects.get(purchase_order = self.purchase_order, product_variant = product_variant)
            unit_price = purchase_order_item.unit_price
            tax_amount =  purchase_order_item.tax_amount
            tax_included = purchase_order_item.tax_included

            if tax_included:
                unit_price_without_tax = unit_price - tax_amount
            else:
                unit_price_without_tax = unit_price
            total_item_price = unit_price_without_tax * quantity
            item_data = {

                'product_variant': product_variant.id,
                'purchase_order_item':purchase_order_item.id,
                'unit_price': unit_price_without_tax,
                'total_price':total_item_price,
                'quantity':quantity,
                'created_by':self.request.user.id

            }
            item.update(item_data)
        return return_items
    
    def remove_duplicate_product_variant_items(self, return_items):
        unique_items = []
        product_variant_id_array_in_return_items = []
        for item in return_items:
            if item['product_variant'] not in product_variant_id_array_in_return_items:
                product_variant_id_array_in_return_items.append(item['product_variant'])
                unique_items.append(item)
        return unique_items
    
    def create_purchase_order_return(self):
        self.request.data['total_return_amount'] =  self.total_return_amount          
        self.request.data['created_by'] = self.request.user.id
        purchase_order_return_serializer = self.serializer_class(data=self.request.data)
        purchase_order_return_serializer.is_valid(raise_exception=True)
        purchase_order_return = purchase_order_return_serializer.save()
        return purchase_order_return, purchase_order_return_serializer

    def create_purchase_order_return_items(self,purchase_order_return):
        [item.update({'purchase_order_return':purchase_order_return.id}) for item in self.return_items]
        purchase_order_return_item_serializer = PurchaseOrderReturnItemSerializer(data=self.return_items, many=True)
        purchase_order_return_item_serializer.is_valid(raise_exception=True)
        purchase_order_return_items = purchase_order_return_item_serializer.save()
        return purchase_order_return_items
    
    def update_product_serial_objects(self):
        for item in self.return_items:
            for serial_number in item['serial_numbers']:
                product_serial = ProductSerial.objects.get(barcode = serial_number)
                product_serial.purchase_order_return = self.purchase_order_return
                product_serial.save()      

    def check_product_serial_and_product_variant_mismatch_and_product_not_returned(self):
        for item in self.return_items:
            product_variant = ProductVariant.objects.get( id = item['product_variant'])
            for serial_number in item['serial_numbers']:
                product_serial = get_object_or_404(ProductSerial,barcode = serial_number)
                print(product_serial.purchase_order_item)
                print( product_variant != product_serial.product_variant)
                return product_serial.purchase_order_item  or product_variant != product_serial.product_variant