def notify_users(send_mail, assigned_users, message): ''' Method to triger notifications ''' notify(users=assigned_users, subject='Stock counts alert', body=message) send_mail.send()
def create_promotion(products, title, discount, outlet): ''' Create promotion for products about to expiry ''' promotion = Promotion.objects.filter(title=title).first() products_added = True if promotion: products_added = not all(product in products for product in promotion.products.all()) promotion.products.add(*products) else: promotion_type, _ = PromotionType.objects.get_or_create(name='expiry') description = 'Products about to expire.' promotion = Promotion(title=title, promotion_type=promotion_type, description=description, discount=discount, is_approved=False, outlet=outlet) with SaveContextManager(promotion, model=Promotion) as promotion: promotion.products.add(*products) if products_added: users = outlet.active_outlet_users roles = ('Master Admin', 'Manager') users = [user for user in users if str(user.role) in roles] message = f'Products have been added to promotion {title}.' notify(users=users, subject='Products about to expire.', body=message)
def notify_quantity(sender, instance, created, **kwargs): """ Method to generate notifications for proposed change in batch quantity. """ if created: if not instance.quantity_remaining and instance.parent is None: instance.quantity_remaining = instance.quantity_received instance.save() if instance.parent_id: batch = instance.batch if len(batch.product.business.outlet_set.all()) > 0: outlet_users = [user for user in batch.product.business.outlet_set.first(). active_outlet_users if user.id != instance.proposed_by.id] all_users = [] if outlet_users: for user in outlet_users: if str(user.role) == "Master\ Admin" or str(user.role) == \ "Operations Admin": all_users.append(user) message = PRODUCTS_SUCCESS_RESPONSES[ "batch_edit_proposal"].format(batch.batch_no) notify( users=all_users, subject='Proposed change in batch quantity', event_name='batch_quantity', body=message) # if quantity instance is not a proposal, # we can check if the product quantity is low if not instance.parent_id: # set an arbitrary quantity threshold # we'll check for instances where product quantity # goes below this threshold quantity_threshold = 50 product = instance.batch.product if len(product.business.outlet_set.all()) > 0: outlet_users = \ product.business.outlet_set.first().active_outlet_users if len(outlet_users) > 0: # notify all outlet users. if product.quantity_in_stock < quantity_threshold: message = PRODUCTS_SUCCESS_RESPONSES[ "low_quantity_alert"].format( product.product_name, product.quantity_in_stock) notify( users=outlet_users, subject='Low quantity alert', event_name='product_quantity', body=message)
def trigger_notification(expired_batches): '''Method to trigger a notification to Master Admin users ''' for batch in expired_batches: outlet = batch['batch'].outlet users = outlet.active_outlet_users outlet_master_admins = [ user for user in users if str(user.role) == 'Master Admin'] batch_number = batch["batch"].batch_no message = f'Products with batch no. { batch_number } are within \ 12 months to expiry!' products = batch['batch'].product.all() product_names = [product.product_name for product in products] html_body = render_to_string( 'batch_expiries/expiry_notification.html', { 'batch': batch['batch'], 'product': product_names, 'outlet': batch['batch'].outlet.name, 'days_to_expiry': batch["days_to_expiry"] }) subject = 'Expired Products!' event_name = 'batch-expiry-notification-event' thread = threading.Thread(target=notify(users=outlet_master_admins, subject=subject, body=message, event_name=event_name, html_body=html_body)) thread.start()
def mutate(self, info, **kwargs): batch_info = kwargs.get('batch_info') quantity_counted = kwargs.get('quantity_counted') stock_count_id = kwargs.get('stock_count_id') validate_stock.stock_validate(kwargs) validate_stock.check_empty_id(stock_count_id, name='Stock Count') stock_count = get_model_object(StockCount, 'id', stock_count_id) validate_stock.check_approved_stock(info, stock_count) validate_stock.add_stock(kwargs, stock_count) validate_stock.validate_batch_ids(stock_count, batch_info) with SaveContextManager(stock_count) as stock_count: if batch_info and quantity_counted: for field, data in enumerate(batch_info): record_instance = \ stock_count.stock_count_record.get(batch_info=data) record_instance.quantity_counted = \ quantity_counted[field] record_instance.save() if stock_count.is_completed: users_instance = \ stock_count.stock_template.designated_users.all() email_stock_count = \ 'email_alerts/stocks/stock_count_email.html' event_name = 'stock_count_approval' subject = 'Stock Count sent for approval' context = { 'template_type': 'Stock Count Approval', 'small_text_detail': 'Stock Count Details', 'email': str(info.context.user.email), 'quantity_counted': str(stock_count.quantity_counted), 'variance_reason': str(stock_count.variance_reason), 'product_quantity': str(stock_count.product.quantity_in_stock) } notify( users=users_instance, subject=subject, event_name=event_name, body=context, html_subject=context, html_body=email_stock_count, ) message = [SUCCESS_RESPONSES["update_success"].format("Stock Count")] return UpdateStockCount(message=message, stock_count=stock_count)
def mutate(cls, root, info, **kwargs): user_ids = kwargs.get('user_ids') subject = kwargs.get('subject') event_name = kwargs.get('event_name') body = kwargs.get('body') users = list(map(lambda user_id: get_model_object( User, 'id', user_id), user_ids)) notifications = notify( users=users, subject=subject, event_name=event_name, body=body) return cls(notifications=notifications)
def generate_expiry_notification(expired_batches): '''Method to trigger a notification to users ''' expired_products = [] outlet_user = [] for batch in expired_batches: outlet = batch['batch'].product.business.outlet_set.first() for user in outlet.active_outlet_users: outlet_user.append(user) message = { 'id': batch['batch'].id, 'batch': batch['batch'].batch_no, 'product': batch['batch'].product.product_name, 'outlet': batch['batch'].product.business.outlet_set.first().name, 'days_to_expiry': batch["days_to_expiry"] } expired_products.append(message) event_name = 'expiry-notification-event' thread = threading.Thread(target=notify(users=outlet_user, subject='Expired Products!', body=message, event_name=event_name, )) thread.start()
def mutate(self, info, **kwargs): validate_stock.stock_validate(kwargs) batch_info = kwargs.get('batch_info') quantity_counted = kwargs.get('quantity_counted') product_id = kwargs.get('product') is_closed = kwargs.get('is_closed', False) product = get_model_object(Product, 'id', product_id) product_batches = product.batch_info.all().values_list('id', flat=True) stock_template = get_model_object(StockCountTemplate, 'id', kwargs.get('stock_template_id')) if stock_template.is_closed: errors.custom_message(STOCK_ERROR_RESPONSES["stock_count_closed"]) stock_template_products = stock_template.products.all() if product not in stock_template_products: errors.custom_message( STOCK_ERROR_RESPONSES["product_template_error"]) message = f'Product {product.product_name} ' + \ STOCK_ERROR_RESPONSES["product_batch_id_error"] check_validity_of_ids(batch_info, product_batches, message=message) stock_count = StockCount() validate_stock.add_stock(kwargs, stock_count) with SaveContextManager(stock_count) as stock_count: message = [ STOCK_SUCCESS_RESPONSES["stock_account_save_in_progress"] ] for index, value in enumerate(batch_info): record_instance = StockCountRecord.objects.create( quantity_counted=quantity_counted[index], batch_info_id=value, ) stock_count.stock_count_record.add(record_instance) if stock_count.is_completed: users_instance = \ stock_count.stock_template.designated_users.all() email_stock_count = \ 'email_alerts/stocks/stock_count_email.html' event_name = 'stock_count_approval' subject = 'Stock Count sent for approval' context = { 'template_type': 'Stock Count Approval', 'small_text_detail': 'Stock Count Details', 'email': str(info.context.user.email), 'quantity_counted': str(stock_count.quantity_counted), 'variance_reason': str(stock_count.variance_reason), 'product_quantity': str(stock_count.product.quantity_in_stock) } notify( users=users_instance, subject=subject, event_name=event_name, body=context, html_subject=context, html_body=email_stock_count, ) message = [STOCK_SUCCESS_RESPONSES["stock_approval_success"]] stock_template.is_closed = is_closed stock_template.save() stock_count.update_template_status return InitiateStockCount(message=message, stock_count=stock_count)