def __Payment(ticket, *args, **kwargs):
    u = User.objects.get(userID=ticket.user.userID)
    if (not u):
        return HttpResponse("error")
    else:
        #Set daily price
        if (ticket.location.lotID == "Motor_Sipil"
                or ticket.location.lotID == "Motor_SR"):
            dailyPrice = 2000
        elif (ticket.location.lotID == "Mobil_SR"):
            dailyPrice = 5000
        else:
            dailyPrice = 0
        #Duration is defined as days that the parking lot is utilized
        dur = (ticket.exitTime - ticket.entryTime).days
        #Duration + 1 since the price is counted since day 0
        total = (dur + 1) * dailyPrice

        if (u.userBalance >= total):
            u.userBalance = u.userBalance - total
            u.save()
            p = Payment(userID=ticket.user,
                        ticketID=Ticket.objects.get(ticketID=ticket.ticketID),
                        duration=dur,
                        amount=total)
            p.save()
            return HttpResponse((
                "You paid IDR {:,} \n Payment successfull, you have IDR {:,} left"
            ).format(total, u.userBalance))
        else:
            ticket.exitTime = None
            ticket.save()
            return HttpResponse("Your balance is not sufficient, Amount = " +
                                str(total))
Exemple #2
0
    def submit_basket(self):
        # Selecting the customer
        customer_id = 1
        if self.selected_customer is not '':
            customer_id = int(self.selected_customer)
        else:
            print('Please select a customer')

        customer = Customer.objects.get(pk=customer_id)

        # Selecting the employee
        employee = User.objects.get(
            pk=1)  # TODO: Modify this after implementing the login

        # Creating the basket
        date_submitted = timezone.now()
        basket = Basket(date_submitted=date_submitted)
        basket.save()

        # Creating the basket lines
        lines_dict = self.products_in_basket
        for line in lines_dict:
            product = Product.objects.get(pk=int(line))
            quantity = lines_dict[line]
            price_excl_tax = product.selling_price
            price_incl_tax = float(product.selling_price) + (
                float(product.selling_price) * float(product.tax_rate)) / 100
            # TODO: This line has to be fed from the Basket Table,
            #  as user can modify prices at checkout
            basket_line = BasketLine(basket=basket,
                                     product=product,
                                     quantity=quantity,
                                     price_excl_tax=price_excl_tax,
                                     price_incl_tax=price_incl_tax)
            basket_line.save()

        # Selecting the payment
        payment_source_text = self.comboBox.currentText()
        payment_source = PaymentSource.objects.get(name=payment_source_text)
        payment_value_date = timezone.now()
        payment = Payment(source=payment_source,
                          date_value=payment_value_date,
                          amount=self.total_basket)
        payment.save()

        sale = Sale(basket=basket,
                    employee=employee,
                    payment=payment,
                    customer=customer)
        # TODO: Need to add Inventory Entries after submitting a sale

        sale.save()

        msg = MessageDialog('The sale has been submitted')
        msg.exec_()
        msg.show()

        self.clear_all()
Exemple #3
0
def make_transaction(user,room):
    tp = PaymentType.objects.get(alias='text-chat')
    user.account = user.account - tp.price
    user.save()
    Payment.get_chat_text_payment_or_create(room)
    # disactive room and note a man
    if user.account<=0:
        room.close_room_by_low_account()
        send_update_room(room)
Exemple #4
0
def register_payment(payment: Payment) -> str:
    """
    - Registers the payment with netaxept.
    - Stores the newly created netaxept transaction_id in the Payment.
    - Records a Transaction representing the registration.

    :param payment: A payment to register.
    :return: The newly created netaxept transaction_id
    :raises NetaxeptException: If the payment was already registered or the registration fails
    """
    logger.info('netaxept-actions-register', payment_id=payment.id)

    if payment.token != '':  # The payment was already registered.
        if payment.is_authorized:
            raise PaymentAlreadyRegisteredAndAuthorized()
        else:
            # If payment was registered but not yet authorized we re-register it so that a later authorize can succeeed.
            # Otherwise when the user gets to the netaxept terminal page he sees a 'payment already processed' error.
            logger.info('netaxept-regegister-payment', payment_id=payment.id)

    _payment_gateway, gateway_config = get_payment_gateway(payment.gateway)
    netaxept_config = gateway_to_netaxept_config(gateway_config)

    try:
        register_response = netaxept_protocol.register(
            config=netaxept_config,
            order_number=payment.id,
            amount=payment.total,
            language='en',
            customer_email=payment.customer_email)
    except NetaxeptProtocolError as exception:
        Transaction.objects.create(payment=payment,
                                   kind=TransactionKind.REGISTER,
                                   token='',
                                   is_success=False,
                                   amount=payment.total,
                                   error=exception.error,
                                   gateway_response=exception.raw_response)
        raise NetaxeptException(exception.error)

    with transaction.atomic():
        payment.token = register_response.transaction_id
        payment.save()

        Transaction.objects.create(
            payment=payment,
            kind=TransactionKind.REGISTER,
            token=register_response.transaction_id,
            is_success=True,
            amount=payment.total,
            error=None,
            gateway_response=register_response.raw_response)

    return register_response.transaction_id
 def create_payment(self):
     payment = Payment(phone='+441784938491',
                       address1='Address1',
                       address2='Address2',
                       city='London',
                       region='Middlesex',
                       post_code='Postcode',
                       country='country',
                       name_on_card='Test Payee',
                       cycle=self.get_cycle())
     payment.save()
Exemple #6
0
def book(request, id):
    book = Book.objects.get(pk=id)
    if not request.user.has_perm('shop.view_book') and book.id == 5:
        pass
    p = Payment(amount=1000, user=request.user, description="Blah Blah")
    p.save()
    return p.pay()

    context = {
        'book': book,
    }
    return render(request, 'shop/book.html', context)
Exemple #7
0
    def get(self, request):
        outsum = request.GET.get('OutSum')
        invid = request.GET.get('InvId')
        user_id = request.GET.get('Shp_user')
        signature = request.GET.get('SignatureValue')
        course_id = request.GET.get('Shp_course')
        try:
            course = Course.objects.get(id=course_id)
            user = User.objects.get(id=user_id)
        except:
            course = None
            user = None
        SignatureValue = hashlib.md5(
            '{}:{}:{}:Shp_course={}:Shp_user={}'.format(
                outsum, invid, PASSWORD2, course_id,
                user_id).encode('utf-8')).hexdigest().upper()
        if signature == SignatureValue:
            Payment(user_id=user_id,
                    money=int(float(outsum)),
                    create_at=datetime.now(),
                    course_id=int(course_id)).save()
            userincourse = UsersInCourse(course_id=course_id,
                                         user_id=user_id,
                                         date=datetime.now()).save()
            # course.users.add(userincourse)
            course.save()

        return Response(data='OK{}'.format(invid))
Exemple #8
0
 def close_room_by_stop_button(self):
     self.is_active = False
     self.is_low_account = False
     self.save()
     p = Payment.get_chat_text_payment_or_create(self)
     p.is_closed = True
     p.save()
Exemple #9
0
    def create(self, request, *args, **kwargs):
        if request.user.is_staff:
            serializer = CoworkingSpaceSubscriptionAdminCreateSerializer(
                data=request.data)
            serializer.is_valid(raise_exception=True)
            self.perform_create(serializer)
            headers = self.get_success_headers(serializer.data)
            return Response(serializer.data,
                            status=status.HTTP_201_CREATED,
                            headers=headers)

        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        # Payment
        package = serializer.validated_data['package']
        payment = Payment.pay(serializer.validated_data['card_token'],
                              package.price)
        if payment is None:
            return Response({"error": "Cannot make payment."},
                            status=status.HTTP_402_PAYMENT_REQUIRED)
        # Date
        date_start = timezone.localdate()
        query = CoworkingSpaceSubscription.objects.filter(
            user=request.user, is_canceled=False, date_end__gte=date_start)
        if query.exists():
            date_start = query.latest('date_end').date_end + timedelta(days=1)
        serializer.save(date_start=date_start,
                        date_end=date_start +
                        timedelta(days=package.duration - 1),
                        payment=payment,
                        user=request.user)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data,
                        status=status.HTTP_201_CREATED,
                        headers=headers)
Exemple #10
0
def payment_process(request):
    order_id = request.session.get('order_id')
    order = get_object_or_404(Order, id=order_id)
    paystack_total = int(order.get_total_cost() * 100)
    data_key = settings.PAYSTACK_PUBLIC_KEY
    data_email = request.user.email

    if request.method == 'POST':

        try:
            payment = Payment()
            payment.paystack_id = request.POST['paystack-trxref']
            payment.customer = request.user
            payment.amount = order.get_total_cost()
            payment.save()

            order.paid = True
            order.ref = request.POST['paystack-trxref']
            order.amount = payment
            order.save()

        except ObjectDoesNotExist:
            pass
        return redirect('payment:success')

    context = {
        'order': order,
        'paystack_total': paystack_total,
        'data_key': data_key,
        'data_email': data_email,
    }
    return render(request, 'payment/process.html', context)
Exemple #11
0
def test_load_from_redis():
    p = Payment({
        'id': 'test',
        'app_id': 'test',
        'transaction_id': 'test',
        'recipient_address': 'test',
        'sender_address': 'test',
        'amount': 1
    })
    Payment(p.to_primitive())
    p.save()
    assert Payment.get('test').amount == p.amount
Exemple #12
0
    def subscribe_for_the_first_time(user, creator=None):
        from payment.models import Payment

        if isinstance(user, BlocklogicUser):
            try:
                subscription = Subscription.objects.get(user=user)

                for p in Payment.objects.filter(status=FIRST_TIME, type=FREE):
                    if subscription in p.subscription.all():
                        return False
            except Subscription.DoesNotExist:
                subscription = Subscription(user=user, days_left=31, created_by=creator)
                subscription.save()

        if isinstance(user, basestring):
            try:
                subscription = Subscription.objects.get(email=user)

                for p in Payment.objects.filter(status=FIRST_TIME, type=FREE):
                    if subscription in p.subscription.all():
                        return False
            except Subscription.DoesNotExist:
                subscription = Subscription(email=user, days_left=31, created_by=creator)
                subscription.save()

        payment = Payment(status=FIRST_TIME, type=FREE, total=0, payment_info=json.dumps({"subscription_duration": 1}), created_by=creator)
        payment.save()

        payment.subscription.add(subscription)
        payment.save()

        start_date = subscription.datetime_created.date()
        end_date = start_date + datetime.timedelta(days=31)

        subscriptions = Subscriptions(subscription=subscription, start_date=start_date, end_date=end_date, payment=payment, status="", period="1", created_by=creator)
        subscriptions.save()

        return True
Exemple #13
0
def get_all(data, db_session, username):
    logger.info(LogMsg.START, username)
    if data.get('sort') is None:
        data['sort'] = ['creation_date-']

    permissions, presses = get_user_permissions(username, db_session)
    has_permission([Permissions.PAYMENT_GET_PREMIUM], permissions)
    logger.debug(LogMsg.PERMISSION_VERIFIED)

    result = Payment.mongoquery(
        db_session.query(Payment)).query(**data).end().all()

    logger.info(LogMsg.END)
    return result
Exemple #14
0
    def insert(self, request_data):
        """ Record a new payment """

        payment = Payment()

        payment.expiration_date = request_data.get('expiration_date')
        payment.value = request_data.get('value')
        payment.branch_id = request_data.get('branch')

        self.__validate_insert(payment)

        payment.save()

        return Payment.objects.get(id=payment.id)
def add_registration(request):
    check_events_happened()
    user = User.objects.get(pk=request.data['user'])
    event = Event.objects.get(pk=request.data['event'])
    p = Payment()
    p.event = event
    try:
        p.method = request.data['method'][0]
        if p.method == 'CashOnSpot':
            r_a = Decimal(0.0)
        else:
            r_a = Decimal(request.data['total_amount'])
    except KeyError:
        p.method = "FREE"
        r_a = Decimal(0.0)
    p.total_amount = Decimal(request.data['total_amount'])
    p.received_amount = r_a
    p.save()
    r = Registration()
    r.event_title = event.title
    r.user = user
    r.event = event
    r.payment = p
    r.number_of_tickets = request.data['number_of_tickets']
    r.price = request.data['price']
    r.voucher_code = ""
    r.total_price = Decimal(request.data['total_amount'])
    r.save()
    if p.method == 'CashOnSpot':
        r.voucher_code = "E" + str(event.id) + "R" + str(r.pk) + "P" + str(
            p.pk) + 'COS'
    else:
        r.voucher_code = "E" + str(event.id) + "R" + str(r.pk) + "P" + str(
            p.pk) + p.method[0]
    r.save()
    event.sold_tickets = event.sold_tickets + r.number_of_tickets
    event.remaining_tickets = event.total_tickets - event.sold_tickets
    event.save()
    return Response({'status': 'OK'})
    def handle(self, *args, **options):
        if len(Account.objects.all()):
            return

        for cur in Account.Currencies:
            acc1 = Account.objects.create(id=uuid.uuid4(),
                                          currency=cur[0],
                                          balance=0)
            acc2 = Account.objects.create(id=uuid.uuid4(),
                                          currency=cur[0],
                                          balance=0)
            Payment.objects.create(account=acc1,
                                   to_account=acc1,
                                   amount=123.12,
                                   direction=Payment.INCOMING)
            acc1.balance = Payment.recalc_account_balance(acc1.id)
            acc1.save()
def get_all(data, db_session, username):
    logger.info(LogMsg.START, username)
    if data.get('sort') is None:
        data['sort'] = ['creation_date-']

    logger.debug(LogMsg.PERMISSION_CHECK, username)
    validate_permissions_and_access(username,
                                    db_session,
                                    'PAYMENT_GET',
                                    access_level=Access_level.Premium)
    logger.debug(LogMsg.PERMISSION_VERIFIED, username)

    result = Payment.mongoquery(
        db_session.query(Payment)).query(**data).end().all()

    logger.info(LogMsg.END)
    return result
    def create(self, request, *args, **kwargs):
        if request.user.is_staff:
            serializer = MeetingRoomBookingAdminCreateSerializer(
                data=request.data)
            serializer.is_valid(raise_exception=True)
            self.perform_create(serializer)
            headers = self.get_success_headers(serializer.data)
            return Response(serializer.data,
                            status=status.HTTP_201_CREATED,
                            headers=headers)

        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        # Date
        room_type = serializer.validated_data['room_type']
        date_start = serializer.validated_data['date_start']
        date_end = serializer.validated_data['date_end']
        room = MeetingRoom.objects.filter(
            type=room_type, is_active=True).exclude(
                meetingroombooking__date_end__gt=date_start,
                meetingroombooking__date_start__lt=date_end,
                meetingroombooking__is_canceled=False).first()
        if room is None:
            return Response({"room_type": "Not available."},
                            status=status.HTTP_400_BAD_REQUEST)
        # Payment
        room_type = serializer.validated_data['room_type']
        payment = Payment.pay(
            serializer.validated_data['card_token'],
            room_type.price * round((date_end - date_start).seconds / 3600))
        if payment is None:
            return Response({"error": "Cannot make payment."},
                            status=status.HTTP_402_PAYMENT_REQUIRED)
        # Save
        serializer.save(room=room, payment=payment, user=request.user)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data,
                        status=status.HTTP_201_CREATED,
                        headers=headers)
Exemple #19
0
def add_payment(data, db_session, username):
    logger.info(LogMsg.START, username)

    model_instance = Payment()
    populate_basic_data(model_instance, username)
    logger.debug(LogMsg.POPULATING_BASIC_DATA)
    model_instance.person_id = data.get('person_id')
    model_instance.amount = data.get('amount')
    model_instance.agent = data.get('agent')
    model_instance.details = data.get('details')
    model_instance.details.update({'call_back_url': data.get('call_back_url')})
    model_instance.order_details = data.get('order_details')
    model_instance.shopping_key = data.get('shopping_key')
    model_instance.reference_code = data.get('reference_code')
    model_instance.used = False
    model_instance.status = 'SendToBank'

    db_session.add(model_instance)
    logger.debug(LogMsg.DB_ADD, model_to_dict(model_instance))

    return model_instance
    def handle(self, *args, **options):

        accounts = Account.objects.filter(payment_on_platform=True)

        month, year = get_last_month()

        for account in accounts:

            try:
                logger.info('Next account {} ({}).'.format(
                    account.id, account.get_name()))

                sync_usage_records(account.license)

                record = LicenseRecord.objects.get(license=account.license,
                                                   month=month,
                                                   year=year)

                logger.info('Last month\'s charge {}'.format(record.total_usd))

                details = {}
                for mac, count in record.details.iteritems():
                    details[mac] = [count, count * settings.PRICE_PER_LICENSE]

                payment = Payment(invoice_id=randint(100000000, 999999999),
                                  account=account,
                                  amount=record.total_usd,
                                  details=details,
                                  month=month,
                                  year=year)

                credits = account.credits.filter(expires__gt=timezone.now(),
                                                 remaining_amount__gt=0.00)

                # For now, we only support one valid credit object at a time
                if len(credits) == 1:

                    credit = credits[0]

                    if credit.remaining_amount > record.total_usd:
                        payment.credits_used = record.total_usd
                        credit.remaining_amount = credit.remaining_amount - record.total_usd

                    else:  # credit.remaining_amount <= self.balance:
                        payment.credits_used = credit.remaining_amount
                        credit.remaining_amount = 0.00

                    credit.save()

                payment.save()

                if len(StripeCustomer.objects.filter(account=account)) == 1:

                    customer = stripe.Customer.retrieve(
                        account.stripe.customer_id)
                    card_details = customer.sources.retrieve(
                        customer.default_source)
                    send_summary_email(payment, record, card_details.last4)

                else:
                    send_summary_email(payment, record)

            except ObjectDoesNotExist as e:
                logger.info(
                    'No license record found for account {}, {}'.format(
                        account, e))

            except Exception as e:
                logger.exception(e)
                logger.error('Billing failed: account {}, {}'.format(
                    account, e))
Exemple #21
0
def register_payment(payment: Payment) -> str:
    """
    This part of the process is unique to netaxept so it cannot be implemented inside the
    payment generic SPI. This implies that a programmer who wants to use the netaxept gateway will have to know
    to call this specific function.

    This function:

    - Registers the payment with netaxept
    - Stores the newly created netaxept transaction_id in the Payment (the transaction_id represents the payment on
       the netaxept side, and needs to be passed to netaxept for further operations like capturing, refunding, etc)
    - Create a Transaction object representing the registration for auditing purposes.

    :param payment: A payment to register
    :return: The the newly created netaxept transaction id
    :raises NetaxeptException: If the payment was already registered or the registration fails
    """
    logger.info('netaxept-actions-register', payment_id=payment.id)

    if payment.token != '':  # The payment was already registered.
        if payment.is_authorized:
            raise PaymentAlreadyRegisteredAndAuthorized()
        else:
            # If payment was registered but not yet authorized we re-register it so that a later authorize can succeeed:
            # Otherwise when the user gets to the netaxept terminal page he sees a 'payment already processed' error.
            logger.info('netaxept-regegister-payment', payment_id=payment.id)

    _payment_gateway, gateway_config = get_payment_gateway(payment.gateway)
    netaxept_config = gateway_to_netaxept_config(gateway_config)

    try:
        register_response = netaxept_protocol.register(
            config=netaxept_config,
            order_number=payment.id,
            amount=payment.total,
            language='en',
            customer_email=payment.customer_email)
    except NetaxeptProtocolError as exception:
        Transaction.objects.create(
            payment=payment,
            kind=TransactionKind.REGISTER,
            token='',
            is_success=False,
            amount=payment.total,
            error=exception.error,
            gateway_response=exception.raw_response)
        raise NetaxeptException(exception.error)

    with transaction.atomic():
        payment.token = register_response.transaction_id
        payment.save()

        Transaction.objects.create(
            payment=payment,
            kind=TransactionKind.REGISTER,
            token=register_response.transaction_id,
            is_success=True,
            amount=payment.total,
            error=None,
            gateway_response=register_response.raw_response)

    return register_response.transaction_id
def process_no_card_payment(request):
    """ Process payment of order using non-card (credit amount) transaction"""
    user = User.objects.get(email=request.user.email)

    # create dummy Payment to indicate a simple credit transaction
    payment = Payment(full_name="Credit payment for " + request.user.username +
                      " @ " + request.user.email,
                      phone_number="n/a",
                      country="n/a",
                      postcode="n/a",
                      town_or_city="n/a",
                      street_address1="n/a",
                      street_address2="n/a",
                      date=timezone.now())
    payment.save()

    total = 0
    user = User.objects.get(email=request.user.email)
    share_order = request.session.get('share_order', {})

    # process each share purchase in the order
    for id, quantity in share_order.items():
        share = get_object_or_404(Share, pk=id)
        total += quantity * share.price
        payment_share_item = PaymentShareItem(payment=payment,
                                              share=share,
                                              quantity=quantity)
        payment_share_item.save()

        # calculate the new price for the share as a result of this purchase
        new_share_price = process_new_price(share.price, quantity, True)
        share.previous_price = share.price
        share.price = new_share_price
        share.save()

        # add to the share quantity for the user
        # if one does not exist, create one
        share_purchase_set = SharePurchase.objects.filter(user=user,
                                                          share=share)
        if len(share_purchase_set) == 0:
            share_purchase = SharePurchase(user=user,
                                           share=share,
                                           quantity=quantity)
        else:
            share_purchase = share_purchase_set[0]
            share_purchase.quantity += quantity

        share_purchase.save()

        # create a history of the share transaction for chart analysis
        share_price_history = SharePriceHistory(
            share=share,
            old_price=share.previous_price,
            new_price=share.price,
            transaction_date=timezone.now())
        share_price_history.save()

    commodity_order = request.session.get('commodity_order', {})

    # process each commodity purchase in the order
    for id, quantity in commodity_order.items():
        commodity = get_object_or_404(Commodity, pk=id)
        total += quantity * commodity.price
        payment_commodity_item = PaymentCommodityItem(payment=payment,
                                                      commodity=commodity,
                                                      quantity=quantity)
        payment_commodity_item.save()

        # calculate the new price for the commodity as a result of this purchase
        new_commodity_price = process_new_price(commodity.price, quantity,
                                                True)
        commodity.previous_price = commodity.price
        commodity.price = new_commodity_price
        commodity.save()

        # add to the commodity quantity for the user
        # if one does not exist, create one
        commodity_purchase_set = CommodityPurchase.objects.filter(
            user=user, commodity=commodity)
        if len(commodity_purchase_set) == 0:
            commodity_purchase = CommodityPurchase(user=user,
                                                   commodity=commodity,
                                                   quantity=quantity)
        else:
            commodity_purchase = commodity_purchase_set[0]
            commodity_purchase.quantity += quantity

        commodity_purchase.save()

        # create a history of the commodity transaction for chart analysis
        commodity_price_history = CommodityPriceHistory(
            commodity=commodity,
            old_price=commodity.previous_price,
            new_price=commodity.price,
            transaction_date=timezone.now())
        commodity_price_history.save()

    messages.error(
        request,
        "You have successfully completed this credit transaction for " +
        str(total))
    wallet_set = Wallet.objects.filter(user=user)

    # Update the credit amount and reset the order
    # and credit amount variables
    wallet = wallet_set[0]
    wallet.credit_amount -= total
    wallet.save()
    request.session['share_order'] = {}
    request.session['commodity_order'] = {}
    request.session['credit_amount'] = str(wallet.credit_amount)
    return redirect(reverse('current_listing'))
    def parse_file(filename):
        log.info("parse file {}".format(filename))

        tree = ET.parse(filename)
        root = tree.getroot()
        payments = []

        ns = {'pf': 'urn:iso:std:iso:20022:tech:xsd:camt.053.001.04'}

        def find_or_empty(transaction, name):
            e = transaction.find(".//pf:{}".format(name), ns)
            return e.text if e is not None else ""

        for transaction in root.findall(".//pf:Ntry", ns):
            # check if transaction id is valid transaction exists already -> skip
            transaction_id = find_or_empty(transaction, 'AcctSvcrRef')
            only_zero_regex = re.compile(r"^0*$")
            if only_zero_regex.match(transaction_id):
                log.warning("A transaction of file {} has an invalid transaction ID: {}".format(filename, transaction_id))
                continue
            log.info("processing transaction {}".format(transaction_id))
            payments_count = Payment.objects.filter(transaction_id=transaction_id).count()
            if payments_count > 0:
                log.warning(
                    "transaction {} in file {} already exists in database".format(transaction_id, filename))
                continue

            payment = Payment()

            # for IBAN transactions
            payment.bic = find_or_empty(transaction, 'BICFI')
            payment.iban = find_or_empty(transaction, 'DbtrAcct')

            # unique reference number by postfinance
            payment.transaction_id = transaction_id
            payment.amount = float(find_or_empty(transaction, 'Amt') or 0.0)
            payment.currency_code = transaction.find('.//pf:Amt', ns).get('Ccy')

            # Credit or Debit
            credit_debit = find_or_empty(transaction, 'CdtDbtInd')
            if credit_debit == 'CRDT':
                payment.credit_debit = Payment.CreditDebit.CREDIT
            elif credit_debit == 'DBIT':
                payment.credit_debit = Payment.CreditDebit.DEBIT
            else:
                payment.credit_debit = Payment.CreditDebit.UNKNOWN

            # remittance user string
            payment.remittance_user_string = find_or_empty(transaction, 'AddtlNtryInf')

            user_data = ISO2022Parser.parse_user_string(payment.remittance_user_string)
            if user_data is not None:
                payment.name = user_data['name']
                payment.address = "{}, {} {}".format(user_data['street'], user_data['plz'], user_data['city'])
                payment.remittance_user_string = user_data['note']

            payment.state = Payment.State.NEW
            # postal_address = debitor.find(".//pf:PstlAdr",ns)
            # if postal_address:
            #    addresses = debitor.findall(".//pf:AdrLine", ns)
            #    payment.address = ", ".join([adr.text for adr in addresses])
            payment.date = datetime.today()  # TODO not exactly elegant
            payment.filename = os.path.split(filename)[-1]
            payments.append(payment)
            log.info('Detected payment: {}'.format(payment))

        return payments
def match_payment(payment_id=None, payment=None, audit_user_id=None):
    if payment is None:
        payment = Payment.filter_queryset().get(id=payment_id)

    payment_details = payment.payment_details.filter(validity_to__isnull=True)

    valid_pd = []
    # validation
    for pd in payment_details:
        errors = validate_payment_detail(pd)
        if len(errors) > 0:
            continue
        valid_pd.append(pd)

        assign_payment_detail(pd, audit_user_id)

    # Only update the policy status for self payer renew (stage R, no officer)
    # contribution without payment (Stage N status READY with officer)
    # PolicyID and phone number required in both cases
    should_update_policy = any(
        ((pd.policy_stage == Policy.STAGE_RENEWED
          and pd.payment.officer_code is None) or
         (pd.policy.status == Policy.STATUS_READY and pd.policy_stage ==
          Policy.STAGE_NEW and pd.payment.officer_code is not None)
         and pd.payment.phone_number is not None and pd.policy is not None)
        for pd in valid_pd)

    if should_update_policy:
        processed = {}
        for pd in valid_pd:
            # recompute policy value for renewal
            new_policy, warnings = policy_values(pd.policy, pd.insuree.family,
                                                 pd.policy)
            if len(warnings) > 0:
                logger.warning("Warning computing the new policy value %s",
                               warnings)
            transaction_no = pd.payment.transaction_no if pd.payment.transaction_no else None

            if ((pd.policy.status == Policy.STATUS_IDLE
                 and pd.policy.stage == Policy.STAGE_RENEWED)
                    and (pd.policy.status == Policy.STATUS_READY
                         and PolicyConfig.activation_option
                         == PolicyConfig.ACTIVATION_OPTION_READY
                         and pd.policy_stage == Policy.STAGE_NEW)
                    and pd.policy.id not in processed):
                if pd.premium.amount >= pd.policy.value:
                    new_policy.save_history()
                    new_policy.status = Policy.STATUS_ACTIVE
                    new_policy.effective_date = pd.policy.start_date
                    set_expiry_date(new_policy)
                    from core import datetime
                    new_policy.validity_from = datetime.datetime.now()
                    new_policy.audit_user_id = audit_user_id
                    new_policy.save()

                    for ip in new_policy.insuree_policies.filter(
                            validity_to__isnull=True):
                        ip.save_history()
                        ip.effective_date = pd.policy.start_date
                        ip.validity_from = datetime.datetime.now()
                        ip.audit_user_id = audit_user_id
                        ip.save()

                    processed[pd.policy.id] = True
            else:
                if pd.policy.status not in [
                        Policy.STATUS_IDLE, Policy.STATUS_READY
                ] and pd.policy.id not in processed:
                    # insert new renewals if the policy is not IDLE
                    set_expiry_date(pd.policy)
                    if pd.amount >= pd.policy.value:
                        pd.policy.status = Policy.STATUS_ACTIVE
                        set_start_date(pd.policy)
                    else:
                        pd.policy.status = Policy.STATUS_IDLE

                    pd.policy.save_history()
                    pd.policy.save()

                    for insuree in pd.insuree.family.members.filter(
                            validity_to__isnull=True):
                        update_insuree_policies(pd.policy, audit_user_id)
                    processed[pd.policy.id] = True
                else:
                    # increment matched payment ?
                    pass

            # insert premiums for individual renewals only
            if pd.premium is None:
                premium, premium_created = Premium.objects.filter(
                    validity_to__isnull=True).update_or_create(
                        policy=pd.policy,
                        amount=pd.amount,
                        type=PayTypeChoices.CASH.value,
                        transaction_no=transaction_no,
                        defaults=dict(
                            audit_user_id=audit_user_id,
                            pay_date=datetime.datetime.now(),
                            validity_from=datetime.datetime.now(),
                        ),
                    )
                pd.premium = premium
                pd.save()
Exemple #25
0
def stripe_webhook(request):
    payload = request.body
    sig_header = request.META['HTTP_STRIPE_SIGNATURE']
    event = None

    try:
        event = stripe.Webhook.construct_event(payload, sig_header,
                                               settings.STRIPE_WEBHOOK_SECRET)
    except ValueError as e:
        # Invalid payload
        return HttpResponse(status=400)
    except stripe.error.SignatureVerificationError as e:
        # Invalid signature
        return HttpResponse(status=400)

    # Handle the checkout.session.completed event
    if event[
            'type'] == 'checkout.session.completed':  # or event['type'] == 'checkout.session.async_payment_succeeded':
        session = event['data']['object']

        # Fulfill the purchase...
        customer_email = session["customer_details"]["email"]
        payment_status = session["payment_status"]
        cacheData = session["metadata"]

        if cacheData and payment_status == 'paid':
            get_session = Session.objects.get(id=cacheData['session_id'])
            patient_email = cacheData['patient_email']
            start_time = cacheData['start_time']
            duration = cacheData['duration']

            try:
                userObject = User.objects.get(email=patient_email)
                patientObject = Patient.objects.get(user=userObject)
            except (User.DoesNotExist, Patient.DoesNotExist):
                # new patient enrolment into the system.
                temp_pass = ''.join(
                    random.choice(string.ascii_uppercase + string.digits)
                    for _ in range(20))
                userObject = createNewUser(patient_email, temp_pass)
                patientObject = createNewPatient(userObject)
                sendMailToNewUser(patient_email, temp_pass)

            if cacheData['consultant'] == 'doctor' and cacheData[
                    'event_type'] == 'single-event':
                doctor = Doctor.objects.get(id=cacheData['consultant_id'])
                new_start_time = datetime.strptime(start_time,
                                                   '%Y-%m-%dT%H:%M:%S')
                new_end_time = new_start_time + timedelta(
                    minutes=int(duration))

                app = Appointment(
                    doctor=doctor,
                    start_time=new_start_time,
                    end_time=new_end_time,
                    session_type=get_session,
                    zoom_link='',
                )
                app.save()
                app.patients.add(patientObject)

            elif cacheData['consultant'] == 'therapist' and cacheData[
                    'event_type'] == 'single-event':
                therapist = Therapist.objects.get(
                    id=cacheData['consultant_id'])
                new_start_time = datetime.strptime(start_time,
                                                   '%Y-%m-%dT%H:%M:%S')
                new_end_time = new_start_time + timedelta(
                    minutes=int(duration))

                app = Appointment(
                    therapist=therapist,
                    start_time=new_start_time,
                    end_time=new_end_time,
                    session_type=get_session,
                    zoom_link='',
                )
                app.save()
                app.patients.add(patientObject)

            elif cacheData['consultant'] == 'doctor' and cacheData[
                    'event_type'] == 'multiple-event':
                doctor = Doctor.objects.get(id=cacheData['consultant_id'])
                start_date_and_time = cacheData['start_time']

                for i in range(int(cacheData['number_of_appointments'])):
                    new_start_time = datetime.strptime(start_date_and_time,
                                                       '%Y-%m-%dT%H:%M:%S')
                    start_dt_for_each_week = new_start_time + timedelta(
                        weeks=i)
                    end_dt_for_each_week = start_dt_for_each_week + timedelta(
                        minutes=int(duration))

                    app = Appointment(
                        doctor=doctor,
                        start_time=start_dt_for_each_week,
                        end_time=end_dt_for_each_week,
                        session_type=get_session,
                        zoom_link='',
                    )
                    app.save()
                    app.patients.add(patientObject)

                    # checking if appointment overlapping.
                    # if Appointment(doctor=doctor, start_time__lt=start_dt_for_each_week, end_time__gt=start_dt_for_each_week).count()>1:
                    # 	print("overlapping")
                    # elif Appointment(doctor=doctor, start_time__lt=end_dt_for_each_week, end_time__gt=end_dt_for_each_week).count()>1:
                    # 	print("overlapping")
                    # elif Appointment(doctor=doctor, start_time__gt=start_dt_for_each_week, end_time__lt=end_dt_for_each_week).count()>1:
                    # 	print("overlapping")
                    # elif Appointment(doctor=doctor, start_time__lt=start_dt_for_each_week, end_time__gt=end_dt_for_each_week).count()>1:
                    # 	print("overlapping")
                    # else:
                    # 	print("clear")

            elif cacheData['consultant'] == 'therapist' and cacheData[
                    'event_type'] == 'multiple-event':
                therapist = Therapist.objects.get(
                    id=cacheData['consultant_id'])
                start_date_and_time = cacheData['start_time']

                for i in range(int(cacheData['number_of_appointments'])):
                    new_start_time = datetime.strptime(start_date_and_time,
                                                       '%Y-%m-%dT%H:%M:%S')
                    start_dt_for_each_week = new_start_time + timedelta(
                        weeks=i)
                    end_dt_for_each_week = start_dt_for_each_week + timedelta(
                        minutes=int(duration))

                    app = Appointment(
                        therapist=therapist,
                        start_time=start_dt_for_each_week,
                        end_time=end_dt_for_each_week,
                        session_type=get_session,
                        zoom_link='',
                    )
                    app.save()
                    app.patients.add(patientObject)

            pay = Payment(user=userObject,
                          payment_status=payment_status.upper(),
                          paymentID=''.join(
                              random.choice(string.ascii_uppercase +
                                            string.digits) for _ in range(10)),
                          session_type=get_session,
                          amount=get_session.get_display_price())
            pay.save()

    # Passed signature verification
    return HttpResponse(status=200)
    def post(self, *args, **kwargs):

        form = PaymentForm(self.request.POST)

        userprofile = User.objects.get(user=self.request.user)
        if form.is_valid():
            data = form.cleaned_data
            token = data.get("stripeToken")
            save = data.get("save")
            use_default = data.get("use_default")

            if save:
                if userprofile.customer_id != "" and userprofile.customer_id is not None:
                    customer = stripe.Customer.retrieve(
                        userprofile.customer_id)
                    customer.sources.create(source=token)

                else:
                    customer = stripe.Customer.create(
                        email=self.request.user.email, )
                    customer.sources.create(source=token)
                    userprofile.stripe_customer_id = customer["id"]
                    userprofile.one_click_purchase = True
                    userprofile.save()
            order = Order.objects.get(user=self.request.user, ordered=False)
            amount = int(order.get_total() * 100)

            try:
                if use_default or save:
                    charge = stripe.Charge.create(
                        amount=amount,
                        currency="gbp",
                        customer=userprofile.stripe_customer_id)
                else:
                    charge = stripe.Charge.create(amount=amount,
                                                  currency="gbp",
                                                  source=token)

                payment = Payment()
                payment.stripe_bill_id = charge["id"]
                payment.user = self.request.user
                payment.amt = order.get_total()
                payment.save()

                order_items = order.products.all()
                order_items.update(ordered=True)
                for item in order_items:
                    item.save()

                order.ordered = True
                order.payment = payment
                order.orderid = generate_order_id()
                order.save()

                messages.success(self.request, "Your order was Successful!")
                return redirect("order_confirmation", orderid=order.orderid)

            except stripe.error.CardError as e:
                body = e.json_body
                err = body.get("error", {})
                messages.warning(self.request, f"{err.get('message')}")
                return redirect("/")

            except stripe.error.RateLimitError as e:
                messages.warning(self.request, "Rate limit error")
                return redirect("/")

            except stripe.error.InvalidRequestError as e:
                messages.warning(self.request, "Invalid parameters")
                return redirect("/")

            except stripe.error.AuthenticationError as e:
                messages.warning(self.request, "Not authenticated")
                return redirect("/")

            except stripe.error.APIConnectionError as e:
                messages.warning(self.request, "Network error")
                return redirect("/")

            except stripe.error.StripeError as e:
                messages.warning(
                    self.request,
                    "Something went wrong. Please try again. You haven't been Charged"
                )
                return redirect("/")

            except Exception as e:
                messages.warning(
                    self.request,
                    "A serious issue occurred. We have been notifed.")
                return redirect("/")

        messages.warning(self.request, "Invalid data received")
        return redirect("/payment/stripe/")
Exemple #27
0
def create_bill_(request, c):
    def item_error(message, product):
        return JsonError(message + " " + _("(Item" + ": ") + product.name + ")")

    # check permissions
    if not has_permission(request.user, c, "bill", "edit"):
        return JsonError(_("You have no permission to create bills"))

    # get data
    data = JsonParse(request.POST.get("data"))
    if not data:
        return JsonError(_("No data received"))

    # see if we're updating an existing bill
    existing_bill = None
    try:
        existing_bill = Bill.objects.get(company=c, id=int(data.get("id")))
        if existing_bill.status == g.PAID:
            return JsonError(_("This bill has already been paid, editing is not possible"))
    except (ValueError, TypeError):
        pass
    except Bill.DoesNotExist:
        pass

    # current company (that will be fixed on this bill forever):
    # save a FK to BillCompany; the last company is the current one
    bill_company = BillCompany.objects.filter(company=c).order_by("-datetime_created")[0]

    # current register: get BillRegister with the same id as current one
    try:
        bill_registers = BillRegister.objects.filter(register__id=int(data.get("register_id")))
        if len(bill_registers) > 0:
            bill_register = bill_registers[0]
        else:
            raise Register.DoesNotExist
    except (TypeError, ValueError, Register.DoesNotExist):
        return JsonError(_("Invalid register specified."))

    # current contact: get BillContact with the same id as the requested contact
    if data.get("contact"):
        try:
            bill_contacts = BillContact.objects.get(contact__id=int(data.get("contact").get("id"))).order_by(
                "datetime_created"
            )
            if len(bill_contacts) > 0:
                bill_contact = bill_contacts[0]
            else:
                raise Contact.DoesNotExist
        except (Contact.DoesNotExist, ValueError, TypeError):
            return JsonError(_("Invalid contact"))
    else:
        bill_contact = None

    # save all validated stuff in bill to a dictionary and insert into database at the end
    # prepare data for insert
    bill = {
        "company": c,
        "issuer": bill_company,
        "register": bill_register,
        "contact": bill_contact,
        "user_id": request.user.id,
        "user_name": str(request.user),
        "notes": data.get("notes", "")[: max_field_length(Bill, "notes")],
        "type": g.CASH,
        "status": g.WAITING,
        "items": [],
        "currency": get_company_value(request.user, c, "pos_currency"),
        # numbers...
        "base": Decimal(0),
        "discount": Decimal(0),
        "tax": Decimal(0),
        "total": Decimal(0),
        "created_by": request.user,
    }

    # timestamp
    try:
        # timestamp: send in an array of number:
        # [year, month, day, hour, minute, second]
        tn = [int(n) for n in data.get("timestamp")]
        bill["timestamp"] = dtm(year=tn[0], month=tn[1], day=tn[2], hour=tn[3], minute=tn[4], second=tn[5])

    except (ValueError, TypeError):
        return JsonError(_("Invalid timestamp"))

    r = parse_decimal(request.user, c, data.get("total"))
    if not r["success"] or r["number"] <= Decimal("0"):
        return JsonError(_("Invalid grand total value"))
    else:
        bill["total"] = r["number"]

    # validate items
    for i in data.get("items"):
        # get product
        try:
            product = Product.objects.get(company=c, id=int(i.get("product_id")))
        except Product.DoesNotExist:
            return JsonError(_("Product with this id does not exist") + " (id=" + i.get("product_id") + ")")

        # parse quantity
        r = parse_decimal(request.user, c, i.get("quantity"), g.DECIMAL["quantity_digits"])
        if not r["success"]:
            return item_error(_("Invalid quantity value"), product)
        else:
            if r["number"] <= Decimal("0"):
                return item_error(_("Cannot add an item with zero or negative quantity"), product)
        quantity = r["number"]

        # remove from stock; TODO: check negative quantities (?)
        # actually we leave negative quantities as they are or
        # when stock is empty, we leave it at 0

        product.destockify(quantity)
        product.save()

        item = {
            "created_by": request.user,
            "code": product.code,
            "shortcut": product.shortcut,
            "name": product.name,
            "description": product.description,
            "private_notes": product.private_notes,
            "unit_type": product.get_unit_type_display(),  # ! display, not the 'code'
            "stock": product.stock,
            # 'bill':  not now, after bill is saved
            "product_id": product.id,
            "bill_notes": i.get("bill_notes"),
            "discounts": [],  # validated discounts (FK in database)
            # prices: will be calculated when discounts are ready
            "base": None,
            "quantity": None,
            "tax_rate": None,
            "batch": None,
            "discount": None,
            "net": None,
            "tax": None,
            "total": None,
        }

        bill["items"].append(item)

        for d in i["discounts"]:
            # check:
            # discount id: if it's -1, it's a unique discount on this item;
            #              if it's anything else, the discount must belong to this company
            #              and must be active and enabled
            d_id = int(d.get("id"))
            if d_id != -1:
                try:
                    dbd = Discount.objects.get(id=d_id, company=c)

                    if not dbd.is_active:
                        return item_error(_("The discount is not active"), product)
                except Discount.DoesNotExist:
                    return item_error(_("Chosen discount does not exist or is not valid"), product)

            # amount: parse number and check that percentage does not exceed 100%
            r = parse_decimal(request.user, c, d.get("amount"))
            if not r["success"]:
                return item_error(_("Invalid discount amount"), product)
            else:
                d_amount = r["number"]
                if d_amount < Decimal(0) or (d.get("type") == "Relative" and d_amount > Decimal(100)):
                    return item_error(_("Invalid discount amount"), product)

            # save data to bill
            discount = {
                "id": d_id,
                "code": d.get("code"),
                "description": d.get("description"),
                "type": d.get("type"),
                "amount": d_amount,
            }
            item["discounts"].append(discount)

        # save this item's prices to item's dictionary (will go into database later)
        try:
            item["base"] = parse_decimal_exc(request.user, c, i.get("base"), message=_("Invalid base price"))
            item["quantity"] = parse_decimal_exc(request.user, c, i.get("quantity"), message=_("Invalid quantity"))
            item["tax_rate"] = parse_decimal_exc(request.user, c, i.get("tax_rate"), message=_("Invalid tax rate"))
            item["batch"] = parse_decimal_exc(request.user, c, i.get("batch"), message=_("Invalid batch price"))
            item["discount"] = parse_decimal_exc(
                request.user, c, i.get("discount"), message=_("Invalid discount amount")
            )
            item["net"] = parse_decimal_exc(request.user, c, i.get("net"), message=_("Invalid net price"))
            item["tax"] = parse_decimal_exc(request.user, c, i.get("tax"), message=_("Invalid tax amount"))
            item["total"] = parse_decimal_exc(request.user, c, i.get("total"), message=_("Invalid total"))

            bill["base"] += item["batch"]
            bill["discount"] += item["discount"]
            bill["tax"] += item["tax"]
        except ValueError as e:
            return item_error(e.message, product)

    # at this point, everything is fine, insert into database
    if existing_bill:
        existing_bill.delete()

    bill_payment = Payment(
        type=g.CASH,
        total=bill["total"],
        currency=get_company_value(request.user, c, "pos_currency"),
        transaction_datetime=datetime.utcnow(),
        status=g.WAITING,
        created_by=request.user,
    )
    bill_payment.save()

    # create a new bill
    db_bill = Bill(
        created_by=request.user,
        company=c,  # current company, FK to Company object
        issuer=bill["issuer"],  # fixed company details at this moment, FK to BillCompany object
        user_id=bill["user_id"],  # id of user that created this bill, just an integer, not a FK
        user_name=bill["user_name"],  # copied user name in case that user gets 'fired'
        register=bill["register"],  # current settings of the register this bill was created on
        contact=bill["contact"],  # FK on BillContact, copy of the Contact object
        notes=bill["notes"],
        # timestamp=dtm.utcnow().replace(tzinfo=timezone(get_company_value(request.user, c, 'pos_timezone'))),
        timestamp=bill["timestamp"],
        payment=bill_payment,
        base=bill["base"],
        discount=bill["discount"],
        tax=bill["tax"],
    )
    db_bill.save()

    # create new items
    for item in bill["items"]:
        db_item = BillItem(
            created_by=item["created_by"],
            code=item["code"],
            shortcut=item["shortcut"],
            name=item["name"],
            description=item["description"],
            private_notes=item["private_notes"],
            unit_type=item["unit_type"],
            bill=db_bill,
            bill_notes=item["bill_notes"],
            product_id=item["product_id"],
            quantity=item["quantity"],
            base=item["base"],
            tax_rate=item["tax_rate"],
            batch=item["batch"],
            discount=item["discount"],
            net=item["net"],
            tax=item["tax"],
            total=item["total"],
        )
        db_item.save()

        # save discounts for this item
        for discount in item["discounts"]:
            db_discount = BillItemDiscount(
                created_by=request.user,
                bill_item=db_item,
                description=discount["description"],
                code=discount["code"],
                type=discount["type"],
                amount=discount["amount"],
            )
            db_discount.save()

    db_bill.save()

    d = {"bill": bill_to_dict(request.user, c, db_bill)}

    return JsonOk(extra=d)