def update_stock(self, product_id): """ Supplier module update stock should always bump product cache and send `shuup.core.signals.stocks_updated` signal. """ supplier_id = self.supplier.pk sv, _ = StockCount.objects.get_or_create(supplier_id=supplier_id, product_id=product_id) if not sv.stock_managed: # item doesn't manage stocks return # TODO: Consider whether this should be done without a cache table values = get_current_stock_value(supplier_id=supplier_id, product_id=product_id) sv.logical_count = values["logical_count"] sv.physical_count = values["physical_count"] latest_event = ( StockAdjustment.objects .filter(supplier=supplier_id, product=product_id, type=StockAdjustmentType.INVENTORY) .last()) if latest_event: sv.stock_value_value = latest_event.purchase_price_value * sv.logical_count if self.supplier.stock_managed and has_installed("shuup.notify"): if sv.alert_limit and sv.physical_count < sv.alert_limit: product = Product.objects.filter(id=product_id).first() if product: from .notify_events import AlertLimitReached for shop in self.supplier.shops.all(): AlertLimitReached(supplier=self.supplier, product=product).run(shop=shop) sv.save(update_fields=("logical_count", "physical_count", "stock_value_value")) context_cache.bump_cache_for_product(Product.objects.get(id=product_id)) stocks_updated.send( type(self), shops=self.supplier.shops.all(), product_ids=[product_id], supplier=self.supplier)
def update_stock(self, product_id): supplier_id = self.supplier.pk # TODO: Consider whether this should be done without a cache table values = get_current_stock_value(supplier_id=supplier_id, product_id=product_id) sv, _ = StockCount.objects.get_or_create(supplier_id=supplier_id, product_id=product_id) sv.logical_count = values["logical_count"] sv.physical_count = values["physical_count"] latest_event = (StockAdjustment.objects.filter( supplier=supplier_id, product=product_id, type=StockAdjustmentType.INVENTORY).last()) if latest_event: sv.stock_value_value = latest_event.purchase_price_value * sv.logical_count if "shuup.notify" in settings.INSTALLED_APPS: if sv.alert_limit and sv.physical_count < sv.alert_limit: product = Product.objects.filter(id=product_id).first() if product and product.stock_behavior == StockBehavior.STOCKED: from .notify_events import AlertLimitReached for shop in self.supplier.shops.all(): AlertLimitReached(supplier=self.supplier, product=product).run(shop=shop) sv.save(update_fields=("logical_count", "physical_count", "stock_value_value")) context_cache.bump_cache_for_product( Product.objects.get(id=product_id))
def update_stock(self, product_id): """ Supplier module update stock should always bump product cache and send `shuup.core.signals.stocks_updated` signal. """ context_cache.bump_cache_for_product(Product.objects.get(id=product_id)) stocks_updated.send(type(self), shops=self.supplier.shops.all(), product_ids=[product_id])
def update_stock(self, product_id, *args, **kwargs): """ Supplier module update stock should always bump product cache and send `shuup.core.signals.stocks_updated` signal. """ supplier_id = self.supplier.pk sv, _ = StockCount.objects.select_related("product").get_or_create( supplier_id=supplier_id, product_id=product_id) # kind not supported if sv.product.kind not in self.get_supported_product_kinds_values(): return # item doesn't manage stocks if not sv.stock_managed: # make sure to index products either way run_task("shuup.simple_supplier.tasks.index_product", product=product_id, supplier=self.supplier.pk) return values = get_current_stock_value(supplier_id=supplier_id, product_id=product_id) sv.logical_count = values["logical_count"] sv.physical_count = values["physical_count"] latest_event = StockAdjustment.objects.filter( supplier=supplier_id, product=product_id, type=StockAdjustmentType.INVENTORY).last() if latest_event: sv.stock_value_value = latest_event.purchase_price_value * sv.logical_count # TODO: get rid of this and move to shuup.notify app instead, through signals if self.supplier.stock_managed and has_installed("shuup.notify"): if sv.alert_limit and sv.physical_count < sv.alert_limit: product = Product.objects.filter(id=product_id).first() if product: from .notify_events import AlertLimitReached for shop in self.supplier.shops.all(): supplier_email = self.supplier.contact_address.email if self.supplier.contact_address else "" shop_email = shop.contact_address.email if shop.contact_address else "" AlertLimitReached( supplier=self.supplier, product=product, shop_email=shop_email, supplier_email=supplier_email, ).run(shop=shop) sv.save(update_fields=("logical_count", "physical_count", "stock_value_value")) context_cache.bump_cache_for_product(product_id) stocks_updated.send(type(self), shops=self.supplier.shops.all(), product_ids=[product_id], supplier=self.supplier) run_task("shuup.simple_supplier.tasks.index_product", product=product_id, supplier=self.supplier.pk)
def update_stock(self, product_id): """ Supplier module update stock should always bump product cache and send `shuup.core.signals.stocks_updated` signal. """ context_cache.bump_cache_for_product(Product.objects.get(id=product_id)) stocks_updated.send( type(self), shops=self.supplier.shops.all(), product_ids=[product_id], supplier=self.supplier)
def create_order(self, order_source): data = self.get_source_base_data(order_source) order = Order(**data) order.save() order = self.finalize_creation(order, order_source) order_creator_finished.send(sender=type(self), order=order, source=order_source) # reset product prices for line in order.lines.exclude(product_id=None): context_cache.bump_cache_for_product(line.product, shop=order.shop) return order
def create_order(self, order_source): data = self.get_source_base_data(order_source) order = Order(**data) order.save() order = self.finalize_creation(order, order_source) order_creator_finished.send(sender=type(self), order=order, source=order_source) # reset product prices for line in order.lines.exclude(product_id=None): context_cache.bump_cache_for_product(line.product, shop=order.shop) return order
def test_bump_caches_signal(rf): """ Test that caches are actually bumped also when calling bump function with id's """ initial_price = 10 shop1 = factories.get_default_shop() shop2 = factories.get_shop(identifier="shop2", domain="shop2") now = datetime(2018, 1, 1, 9, 0, tzinfo=pytz.UTC) # 01/01/2018 09:00 AM def assert_cache_bumped(prods): for sp in prods: key, val = context_cache.get_cached_value( identifier="is_orderable", item=sp, context={"customer": contact}, supplier=factories.get_default_supplier(), stock_managed=bool( factories.get_default_supplier() and factories.get_default_supplier().stock_managed), quantity=1, allow_cache=True) assert val == None with patch("django.utils.timezone.now", new=lambda: now): product1 = factories.create_product( "product", shop=shop1, supplier=factories.get_default_supplier(), default_price=initial_price) product2 = factories.create_product( "product2", shop=shop2, supplier=factories.get_default_supplier(), default_price=20) user = factories.create_random_user() contact = get_person_contact(user) shop_product1 = product1.shop_products.filter(shop=shop1).first() shop_product2 = product2.shop_products.filter(shop=shop2).first() assert shop_product1.is_orderable( factories.get_default_supplier(shop1), contact, 1) is True assert shop_product2.is_orderable( factories.get_default_supplier(shop2), contact, 1) is True # Test single product id bumping context_cache.bump_cache_for_product(product2.id, shop=shop2) context_cache.bump_cache_for_product(product1.id, shop=shop1) assert_cache_bumped([shop_product1, shop_product2]) # Test list bumping context_cache.bump_cache_for_product([product2.id], shop=shop2) context_cache.bump_cache_for_product([product1.id], shop=shop1) assert_cache_bumped([shop_product1, shop_product2])
def update_stock(self, product_id): """ Supplier module update stock should always bump product cache and send `shuup.core.signals.stocks_updated` signal. """ supplier_id = self.supplier.pk sv, _ = StockCount.objects.get_or_create(supplier_id=supplier_id, product_id=product_id) if not sv.stock_managed: # item doesn't manage stocks return # TODO: Consider whether this should be done without a cache table values = get_current_stock_value(supplier_id=supplier_id, product_id=product_id) sv.logical_count = values["logical_count"] sv.physical_count = values["physical_count"] latest_event = ( StockAdjustment.objects .filter(supplier=supplier_id, product=product_id, type=StockAdjustmentType.INVENTORY) .last()) if latest_event: sv.stock_value_value = latest_event.purchase_price_value * sv.logical_count if self.supplier.stock_managed and has_installed("shuup.notify"): if sv.alert_limit and sv.physical_count < sv.alert_limit: product = Product.objects.filter(id=product_id).first() if product: from .notify_events import AlertLimitReached for shop in self.supplier.shops.all(): supplier_email = self.supplier.contact_address.email if self.supplier.contact_address else "" shop_email = shop.contact_address.email if shop.contact_address else "" AlertLimitReached( supplier=self.supplier, product=product, shop_email=shop_email, supplier_email=supplier_email ).run(shop=shop) sv.save(update_fields=("logical_count", "physical_count", "stock_value_value")) context_cache.bump_cache_for_product(Product.objects.get(id=product_id)) stocks_updated.send( type(self), shops=self.supplier.shops.all(), product_ids=[product_id], supplier=self.supplier)
def process_stock_managed(request, supplier_id, product_id): if request.method != "POST": raise Exception(_("Not allowed")) stock_managed = bool(request.POST.get("stock_managed") == "True") supplier = Supplier.objects.get(id=supplier_id) product = Product.objects.get(id=product_id) stock_count = StockCount.objects.get_or_create(supplier=supplier, product=product)[0] stock_count.stock_managed = stock_managed stock_count.save(update_fields=["stock_managed"]) for shop in supplier.shops.all(): context_cache.bump_cache_for_product(product, shop=shop) if stock_managed: msg = _("Stock management is now enabled for {product}").format(product=product) else: msg = _("Stock management is now disabled for {product}").format(product=product) success_message = _get_success_message(request, supplier, product, msg) return JsonResponse(success_message, status=200)
def save(self, *args, **kwargs): super(CgpDiscount, self).save(*args, **kwargs) # check if there is a shop product before bumping the cache if self.product.shop_products.filter(shop_id=self.shop.id).exists(): bump_cache_for_product(self.product, self.shop)
def on_order_creator_finished(sender, order, source, **kwargs): # reset product prices for product_id, shop_id in order.lines.exclude( product__isnull=False).values_list("product_id", "order__shop_id"): context_cache.bump_cache_for_product(product_id, shop_id)
def save(self, *args, **kwargs): super(CgpPrice, self).save(*args, **kwargs) bump_cache_for_product(self.product, self.shop)
def save(self, *args, **kwargs): super(CgpDiscount, self).save(*args, **kwargs) # check if there is a shop product before bumping the cache if self.product.shop_products.filter(shop_id=self.shop.id).exists(): bump_cache_for_product(self.product, self.shop)
def save(self, *args, **kwargs): super(CgpPrice, self).save(*args, **kwargs) bump_cache_for_product(self.product, self.shop)