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)
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)
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')
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)
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')
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)
def delete(self, *args, **kwargs): super(Product, self).delete(*args, **kwargs) from ikwen_kakocase.kako.utils import mark_duplicates mark_duplicates(self)