Example #1
0
def submit_order_for_bank_approval(request, order, bank_id, account_number, deal_id=None):
    merchant = get_service_instance()
    bank = Service.objects.get(pk=bank_id)
    payment_mean = PaymentMean.objects.get(slug=bank.project_name_slug)
    order.payment_mean = payment_mean
    entry = order.entries[0]
    product = entry.product
    product.stock -= entry.count
    if product.stock == 0:
        sudo_group = Group.objects.get(name=SUDO)
        add_event(merchant, SOLD_OUT_EVENT, group_id=sudo_group.id, object_id=product.id)
        mark_duplicates(product)
    product.save()
    bank_db = bank.database
    add_database(bank_db)
    try:
        member = Member.objects.using(bank_db).get(pk=order.member.id)
    except Member.DoesNotExist:
        member = order.member
        member.save(using=bank_db)
        group = Group.objects.using(bank_db).get(name=COMMUNITY)
        obj_list, created = UserPermissionList.objects.using(bank_db).get_or_create(user=member)
        obj_list.group_fk_list.append(group.id)
        obj_list.save(using=bank_db)
    account_number_slug = slugify(account_number)
    try:
        BankAccount.objects.using(UMBRELLA).get(slug=account_number_slug)
    except BankAccount.DoesNotExist:
        m = Member.objects.using(UMBRELLA).get(pk=member.id)
        b = Service.objects.using(UMBRELLA).get(pk=bank_id)
        BankAccount.objects.using(UMBRELLA).create(member=m, bank=b, number=account_number, slug=account_number_slug)
    if deal_id:
        if len(order.entries) > 1:
            messages.error(request, _("Terms payment is available only for one single product at a time."))
            return HttpResponseRedirect(reverse('shopping:cart'))
        deal = Deal.objects.using(bank_db).get(pk=deal_id)
    else:
        deal = Deal(bank=bank)
    order.deal = deal
    order.account_number = account_number
    order.status = Order.PENDING_FOR_APPROVAL
    order.save()
    order.save(using=bank_db)
    try:
        del(request.session['object_id'])
    except:
        pass
    subject = _("Order submit for approval")
    send_order_confirmation_email(request, subject, member.full_name, member.email, order)
    bank_profile_original = OperatorProfile.objects.using(bank_db).get(service=bank)
    if bank_profile_original.return_url:
        nvp_dict = {'member': member.full_name, 'email': member.email, 'phone': member.phone,
                    'order_rcc': order.rcc.upper(), 'account_number': account_number,
                    'deal': str(deal), 'merchant': merchant.project_name}
        Thread(target=lambda url, data: requests.post(url, data=data),
               args=(bank_profile_original.return_url, nvp_dict)).start()

    next_url = reverse('shopping:cart', args=(order.id, ))
    return HttpResponseRedirect(next_url)
Example #2
0
 def test_mark_duplicates(self):
     """
     Product.get_size_list returns a list of all sizes of Products with same slug, category and brand.
     """
     brand = 'Same Brand'
     c = ProductCategory.objects.all()[0]
     slug = 'same-slug'
     Product.objects.filter(pk='55d1fa8feb60008099bd4151').update(category=c, slug=slug, brand=brand, size="S", stock=10)
     Product.objects.filter(pk='55d1fa8feb60008099bd4152').update(category=c, slug=slug, brand=brand, size="M", stock=5)
     Product.objects.filter(pk='55d1fa8feb60008099bd4153').update(category=c, slug=slug, brand=brand, size="L", stock=7)
     p1 = Product.objects.get(pk='55d1fa8feb60008099bd4151')
     mark_duplicates(p1)
     p2 = Product.objects.get(pk='55d1fa8feb60008099bd4152')
     p3 = Product.objects.get(pk='55d1fa8feb60008099bd4153')
     self.assertTrue(p2.is_duplicate)
     self.assertTrue(p3.is_duplicate)
     self.assertFalse(p1.is_duplicate)
     p1.delete()
     p2 = Product.objects.get(pk='55d1fa8feb60008099bd4152')
     self.assertTrue(p2.is_duplicate)
Example #3
0
def update_product_stock(request, *args, **kwargs):
    """
    Update stock :class:`kako.models.Product` in the actual :class:`ikwen.ikwen_kakocase.models.OperatorProfile` database.
    This method assumes only provider can update stock. So the Product.save() is called only with the default database
    """
    product_id = request.GET['product_id']
    stock = float(request.GET['stock'])
    try:
        product = Product.objects.get(pk=product_id)
        product.stock = stock
        product.save()
        if stock == 0:
            mark_duplicates(product)
        operator_profile_umbrella = get_service_instance(UMBRELLA).config
        operator_profile_umbrella.stock_updated_on = timezone.now()
        operator_profile_umbrella.last_stock_update_method = OperatorProfile.MANUAL_UPDATE
        operator_profile_umbrella.save(using=UMBRELLA)
    except Product.DoesNotExist:
        response = {'error': "Product not found."}
    else:
        response = {'success': True}
    return HttpResponse(json.dumps(response), 'content-type: text/json')
Example #4
0
def after_order_confirmation(order, update_stock=True):
    member = order.member
    service = get_service_instance()
    config = service.config
    delcom = order.delivery_option.company
    delcom_db = delcom.database
    add_database(delcom_db)
    delcom_profile_original = OperatorProfile.objects.using(delcom_db).get(pk=delcom.config.id)
    dara, dara_service_original, provider_mirror = None, None, None
    sudo_group = Group.objects.get(name=SUDO)
    customer = member.customer
    referrer = customer.referrer
    referrer_share_rate = 0

    # Test if the customer has been referred
    if referrer:
        referrer_db = referrer.database
        add_database(referrer_db)
        try:
            dara = Dara.objects.get(member=referrer.member)
        except Dara.DoesNotExist:
            logging.error("%s - Dara %s not found" % (service.project_name, member.username))
        try:
            dara_service_original = Service.objects.using(referrer_db).get(pk=referrer.id)
        except Dara.DoesNotExist:
            logging.error("%s - Dara service not found in %s database for %s" % (service.project_name, referrer_db, referrer.project_name))
        try:
            provider_mirror = Service.objects.using(referrer_db).get(pk=service.id)
        except Service.DoesNotExist:
            logging.error("%s - Provider Service not found in %s database for %s" % (service.project_name, referrer_db, referrer.project_name))

    packages_info = order.split_into_packages(dara)

    if delcom != service and delcom_profile_original.payment_delay == OperatorProfile.STRAIGHT:
        set_logicom_earnings_and_stats(order)

    for provider_db in packages_info.keys():
        package = packages_info[provider_db]['package']
        provider_earnings = package.provider_earnings
        raw_provider_revenue = package.provider_revenue
        provider_revenue = raw_provider_revenue
        if package.provider == delcom:
            provider_revenue += order.delivery_option.cost + order.delivery_option.packing_cost
            provider_earnings += order.delivery_earnings
        else:
            provider_revenue += order.delivery_option.packing_cost
            provider_earnings += order.delivery_option.packing_cost * (100 - config.ikwen_share_rate) / 100
        provider_profile_umbrella = packages_info[provider_db]['provider_profile']
        provider_profile_original = provider_profile_umbrella.get_from(provider_db)
        provider_original = provider_profile_original.service

        if delcom == service:
            provider_original.raise_balance(provider_earnings, provider=order.payment_mean.slug)
        else:
            if delcom_profile_original.return_url:
                nvp_dict = package.get_nvp_api_dict()
                Thread(target=lambda url, data: requests.post(url, data=data),
                       args=(delcom_profile_original.return_url, nvp_dict)).start()
            if provider_profile_original.payment_delay == OperatorProfile.STRAIGHT:
                if package.provider_earnings > 0:
                    provider_original.raise_balance(provider_earnings, provider=order.payment_mean.slug)
        if provider_profile_original.return_url:
            nvp_dict = package.get_nvp_api_dict()
            Thread(target=lambda url, data: requests.post(url, data=data),
                   args=(provider_profile_original.return_url, nvp_dict)).start()

    set_counters(config)
    increment_history_field(config, 'orders_count_history')
    increment_history_field(config, 'items_traded_history', order.items_count)
    increment_history_field(config, 'turnover_history', provider_revenue)
    increment_history_field(config, 'earnings_history', provider_earnings)

    set_counters(customer)
    customer.last_payment_on = datetime.now()
    increment_history_field(customer, 'orders_count_history')
    increment_history_field(customer, 'items_purchased_history', order.items_count)
    increment_history_field(customer, 'turnover_history', provider_revenue)
    increment_history_field(customer, 'earnings_history', provider_earnings)

    # Test whether the referrer (of the current customer) is a Dara
    if dara:
        referrer_share_rate = dara.share_rate
        send_dara_notification_email(dara_service_original, order)

        set_counters(dara)
        dara.last_transaction_on = datetime.now()

        increment_history_field(dara, 'orders_count_history')
        increment_history_field(dara, 'items_traded_history', order.items_count)
        increment_history_field(dara, 'turnover_history', provider_revenue)
        increment_history_field(dara, 'earnings_history', provider_earnings)

        if dara_service_original:
            set_counters(dara_service_original)
            increment_history_field(dara_service_original, 'transaction_count_history')
            increment_history_field(dara_service_original, 'turnover_history', raw_provider_revenue)
            increment_history_field(dara_service_original, 'earnings_history', order.referrer_earnings)

        if dara_service_original:
            set_counters(provider_mirror)
            increment_history_field(provider_mirror, 'transaction_count_history')
            increment_history_field(provider_mirror, 'turnover_history', raw_provider_revenue)
            increment_history_field(provider_mirror, 'earnings_history', order.referrer_earnings)

        try:
            member_ref = Member.objects.using(referrer_db).get(pk=member.id)
        except Member.DoesNotExist:
            member.save(using=referrer_db)
            member_ref = Member.objects.using(referrer_db).get(pk=member.id)
            member.customer.save(using=referrer_db)
        customer_ref = member_ref.customer
        set_counters(customer_ref)
        customer_ref.last_payment_on = datetime.now()
        increment_history_field(customer_ref, 'orders_count_history')
        increment_history_field(customer_ref, 'items_purchased_history', order.items_count)
        increment_history_field(customer_ref, 'turnover_history', raw_provider_revenue)
        increment_history_field(customer_ref, 'earnings_history', order.retailer_earnings)

        dara_umbrella = Dara.objects.using(UMBRELLA).get(member=dara.member)
        if dara_umbrella.level == 1 and dara_umbrella.xp == 2:
            dara_umbrella.xp = 3
            dara_umbrella.raise_bonus_cash(200)
            dara_umbrella.save()

    category_list = []

    # Adding a 100 bonus in dara account to have buy online
    try:
        dara_as_buyer = Dara.objects.using(UMBRELLA).get(member=member)
        if dara_as_buyer.level == 1 and dara_as_buyer.xp == 0:
            dara_as_buyer.xp = 1
            dara_as_buyer.raise_bonus_cash(100)
            dara_as_buyer.save()
    except Dara.DoesNotExist:
        logging.error("The customer is not yet a Dara")

    for entry in order.entries:
        product = Product.objects.get(pk=entry.product.id)
        provider_service = product.provider
        provider_profile_umbrella = OperatorProfile.objects.using(UMBRELLA).get(service=provider_service)
        category = product.category

        turnover = entry.count * product.retail_price
        set_counters(category)
        provider_earnings = turnover * (100 - referrer_share_rate - provider_profile_umbrella.ikwen_share_rate) / 100
        increment_history_field(category, 'earnings_history', provider_earnings)
        increment_history_field(category, 'turnover_history', turnover)
        increment_history_field(category, 'items_traded_history', entry.count)
        if category not in category_list:
            increment_history_field(category, 'orders_count_history')
            category_list.append(category)

        if update_stock:
            product.stock -= entry.count
            if product.stock == 0:
                add_event(service, SOLD_OUT_EVENT, group_id=sudo_group.id, object_id=product.id)
                mark_duplicates(product)
        product.save()
        set_counters(product)
        increment_history_field(product, 'units_sold_history', entry.count)

    add_event(service, NEW_ORDER_EVENT, group_id=sudo_group.id, object_id=order.id)
Example #5
0
def after_order_confirmation(order, media_order=None, update_stock=True):
    member = order.member
    service = get_service_instance()
    config = service.config
    delcom = order.delivery_option.company
    delcom_db = delcom.database
    add_database(delcom_db)
    sudo_group = Group.objects.get(name=SUDO)
    customer = member.customer
    packages_info = order.split_into_packages()

    for provider_db in packages_info.keys():
        package = packages_info[provider_db]['package']
        provider_earnings = package.provider_earnings
        raw_provider_revenue = package.provider_revenue
        provider_revenue = raw_provider_revenue
        if package.provider == delcom:
            provider_revenue += order.delivery_option.cost + order.delivery_option.packing_cost
            provider_earnings += order.delivery_earnings
        else:
            provider_revenue += order.delivery_option.packing_cost
            provider_earnings += order.delivery_option.packing_cost * (100 - config.ikwen_share_rate) / 100
        provider_profile_umbrella = packages_info[provider_db]['provider_profile']
        provider_profile_original = provider_profile_umbrella.get_from(provider_db)

        if provider_profile_original.return_url:
            nvp_dict = package.get_nvp_api_dict()
            Thread(target=lambda url, data: requests.post(url, data=data),
                   args=(provider_profile_original.return_url, nvp_dict)).start()

    if media_order:
        provider_revenue += media_order.total_cost
        provider_earnings += media_order.total_cost

    set_counters(config)
    increment_history_field(config, 'orders_count_history')
    increment_history_field(config, 'items_traded_history', order.items_count)
    increment_history_field(config, 'turnover_history', provider_revenue)
    increment_history_field(config, 'earnings_history', provider_earnings)

    set_counters(customer)
    customer.last_payment_on = datetime.now()
    increment_history_field(customer, 'orders_count_history')
    increment_history_field(customer, 'items_purchased_history', order.items_count)
    increment_history_field(customer, 'turnover_history', provider_revenue)
    increment_history_field(customer, 'earnings_history', provider_earnings)

    category_list = []
    for entry in order.entries:
        product = Product.objects.get(pk=entry.product.id)
        category = product.category

        turnover = entry.count * product.retail_price
        set_counters(category)
        provider_earnings = turnover
        increment_history_field(category, 'earnings_history', provider_earnings)
        increment_history_field(category, 'turnover_history', turnover)
        increment_history_field(category, 'items_traded_history', entry.count)
        if category not in category_list:
            increment_history_field(category, 'orders_count_history')
            category_list.append(category)

        if update_stock:
            product.stock -= entry.count
            if product.stock == 0:
                add_event(service, SOLD_OUT_EVENT, group_id=sudo_group.id, object_id=product.id)
                mark_duplicates(product)
        product.save()
        set_counters(product)
        increment_history_field(product, 'units_sold_history', entry.count)

    for album in media_order.album_list:
        set_counters(album)
        increment_history_field(album, 'earnings_history', album.cost)
        increment_history_field(album, 'turnover_history', album.cost)
        increment_history_field(album, 'units_sold_history')

    for song in media_order.song_list:
        if song.cost == 0:
            continue
        set_counters(song)
        increment_history_field(song, 'earnings_history', song.cost)
        increment_history_field(song, 'turnover_history', song.cost)
        increment_history_field(song, 'units_sold_history')
Example #6
0
    def post(self, request, *args, **kwargs):
        service = get_service_instance()
        config = service.config
        object_id = kwargs.get('object_id', request.POST.get('object_id'))
        product_admin = get_model_admin_instance(self.model, self.model_admin)
        if object_id:
            obj = self.get_object(**kwargs)
        else:
            obj = self.model()
        model_form = product_admin.get_form(request)
        form = model_form(request.POST, instance=obj)
        if form.is_valid():
            name = request.POST.get('name')
            category_id = request.POST.get('category')
            brand = request.POST.get('brand')
            reference = request.POST.get('reference')
            original_id = request.POST.get('original_id')
            wholesale_price = float(request.POST.get('wholesale_price'))
            packing_price = float(request.POST.get('packing_price'))
            try:
                retail_price = float(request.POST.get('retail_price'))
            except:
                retail_price = 0
            max_price = request.POST.get('max_price')
            summary = request.POST.get('summary')
            description = request.POST.get('description')
            badge_text = request.POST.get('badge_text')
            size = request.POST.get('size')
            weight = request.POST.get('weight')
            stock = request.POST.get('stock')
            unit_of_measurement = request.POST.get('unit_of_measurement')
            min_order = request.POST.get('min_order')
            if not min_order:
                min_order = 1
            visible = request.POST.get('visible')
            photos_ids = request.POST.get('photos_ids')
            photos_ids_list = photos_ids.strip(',').split(',') if photos_ids else []
            category = ProductCategory.objects.get(pk=category_id)
            do_revive = False
            if retail_price and retail_price < wholesale_price:
                error = _("Retail price cannot be smaller than wholesale price.")
                context = self.get_context_data(**kwargs)
                context['error'] = error
                return render(request, self.template_name, context)
            if object_id:
                product = get_object_or_404(Product, pk=object_id)
                if getattr(settings, 'IS_PROVIDER', False):
                    if product.is_retailed:
                        error = _("Product already imported by some retailers. Delete and start again.")
                        context = self.get_context_data(**kwargs)
                        context['error'] = error
                        return render(request, self.template_name, context)

                if product.retail_price_is_modifiable and retail_price < product.retail_price:
                    product.previous_price = product.retail_price
                    product.on_sale = True
                    do_revive = True
                else:
                    product.on_sale = False
                if product.category != category:
                    product.category.items_count -= 1
                    product.category.save()
            else:
                if not config.is_pro_version and config.max_products == Product.objects.filter(in_trash=False).count():
                    error = _("Product cannot be added because the limit of %d products is reached." % config.max_products)
                    context = self.get_context_data(**kwargs)
                    context['error'] = error
                    return render(request, self.template_name, context)
                category.items_count = category.product_set.all().count() + 1
                product = Product(units_sold_history=[0])
                try:
                    previous_product_add = Product.objects.all().order_by('-id')[0].created_on
                    diff = datetime.now() - previous_product_add
                    if diff.days > 3:
                        do_revive = True
                except:
                    do_revive = True
                product.order_of_appearance = Product.objects.all().count() + 1
            # if product.id is not None and product.provider != operator:
            #     return HttpResponseForbidden("You don't have permission to access this resource.")
            product.name = name
            product.slug = slugify(name)
            product.brand = brand.strip()
            product.summary = summary
            product.description = description
            product.badge_text = badge_text
            product.category = category
            product.reference = reference
            product.original_id = original_id
            product.size = size
            product.weight = weight
            product.min_order = min_order
            product.packing_price = packing_price
            product.unit_of_measurement = unit_of_measurement
            product.tags = product.slug.replace('-', ' ')
            try:
                product.stock = int(stock.strip())
            except:
                product.stock = 0
            if getattr(settings, 'IS_PROVIDER', False):
                product.wholesale_price = wholesale_price
                if max_price:
                    product.max_price = float(max_price.strip())
                product.retail_price_is_modifiable = True if request.POST.get('retail_price_is_modifiable') else False
            else:
                product.retail_price_is_modifiable = True
            product.photos = []
            if len(photos_ids_list) == 0:
                product.visible = False  # Product without photo are hidden
            else:
                product.visible = True if visible else False  # Product with photo has visibility chosen by user
                for photo_id in photos_ids_list:
                    if photo_id:
                        try:
                            photo = Photo.objects.get(pk=photo_id)
                            product.photos.append(photo)
                        except:
                            pass
            if retail_price:
                product.retail_price = retail_price
            product.provider = service
            product.save()
            category.save()
            if not config.is_pro_version:
                total_products_count = Product.objects.filter(in_trash=False).count()
                if config.max_products == (total_products_count - 10):
                    product_manager_list = get_members_having_permission(Product, 'ik_manage_product')
                    for m in product_manager_list:
                        add_event(service, PRODUCTS_LIMIT_ALMOST_REACHED_EVENT, m)
                if config.max_products == total_products_count - 10:
                    product_manager_list = get_members_having_permission(Product, 'ik_manage_product')
                    for m in product_manager_list:
                        add_event(service, PRODUCTS_LIMIT_REACHED_EVENT, m)
            if object_id:
                next_url = reverse('kako:change_product', args=(object_id, ))
                messages.success(request, _("Product %s successfully updated." % product.name))
            else:
                add_event(service, PRODUCT_PUBLISHED_EVENT, object_id=product.id, model='kako.Product')
                next_url = reverse('kako:product_list')
                messages.success(request, _("Product %s successfully created." % product.name))
            mark_duplicates(product)
            tag = '__' + category.slug
            category_auto_profile_tag, update = ProfileTag.objects.get_or_create(name=category.name, slug=tag, is_auto=True)
            auto_profiletag_id_list = [category_auto_profile_tag.id]
            revival_mail_renderer = 'ikwen_kakocase.kako.utils.render_products_added'
            if product.on_sale:
                revival_mail_renderer = 'ikwen_kakocase.kako.utils.render_product_on_sale'

            self.save_object_profile_tags(request, product, auto_profiletag_id_list=auto_profiletag_id_list,
                                          do_revive=do_revive, revival_mail_renderer=revival_mail_renderer, **kwargs)
            return HttpResponseRedirect(next_url)
        else:
            context = self.get_context_data(**kwargs)
            admin_form = helpers.AdminForm(form, list(product_admin.get_fieldsets(self.request)),
                                           product_admin.get_prepopulated_fields(self.request),
                                           product_admin.get_readonly_fields(self.request))
            context['model_admin_form'] = admin_form
            messages.error(request, _("Product was not created. One ore more fields were invalid."))
            return render(request, self.template_name, context)
Example #7
0
 def delete(self, *args, **kwargs):
     super(Product, self).delete(*args, **kwargs)
     from ikwen_kakocase.kako.utils import mark_duplicates
     mark_duplicates(self)