def get_popular_demand(role, user, page, t1id, aid, asc_of_price, count_per_page): """ :param role: :param user: :param page: start from one :param count_per_page: size of page :return: """ if user is None and role is None: raise Error400("Either user or role must not be null.") if user is not None: role = user.role qs = ProductDemand.objects.select_related( 'uid__user_validate', 'qid__t3id__t2id__t1id', 'aid__cid__pid', 'pmid', 'wcid').filter(in_use=True, match=True).filter(end_time__gt=now()).exclude( t_demand=t_demand_translator.from_role(role)) qs = filter_and_order_demand(qs, t1id, aid, asc_of_price) st, ed, n_pages = get_page_info( qs, count_per_page, page, index_error_excepiton=Error400("Page out of range")) # return sliced single page return qs[st:ed], n_pages
def validate_satisfy_demand(self, opposite_role, quantity): """ Raise WLError if not satisfied. :param opposite_role: :param quantity: :return: """ if not self.in_use: raise WLException(404, "No such demand - not in use") # Validate expire date # TODO: Check whether "now" works if self.st_time + datetime.timedelta(days=self.duration) < now(): raise WLException(404, "No such demand - expire") if opposite_role == self.uid.role: raise WLException(404, "No such demand - role does not match") if quantity < self.min_quantity: raise WLException(403, "Min Quantity not satisfied") # Validate whether quantity meets quantity - satisfied if quantity > self.quantity_left(): raise WLException(403, "Exceed max quantity") return
def validate_satisfy_demand(self, opposite_role, quantity=None, quantity_metric=None): """ Raise WLError if not satisfied. :param opposite_role: :param quantity_metric: :param quantity: :return: """ if quantity_metric is None: quantity_metric = UnitQuantityMetric(quantity, self.unit) if not self.in_use: raise WLException(404, "No such demand - not in use") # Validate expire date # TODO: Check whether "now" works if self.end_time < now(): raise WLException(404, "No such demand - expire") if opposite_role == self.uid.role: raise WLException(404, "No such demand - role does not match") if quantity_metric < self.min_quantity_metric(): raise WLException(403, "Min Quantity not satisfied") # Validate whether quantity meets quantity - satisfied if quantity_metric > self.quantity_left(): raise WLException(403, "Exceed max quantity") return
def get_matched_demand(user, id, page, order, asc, count_per_page): """ :param user: :param id: :param page: :param order: :param count_per_page: :return: """ def confirm_satisfied(self, other): # type: (ProductDemand, ProductDemand) -> bool return self.quantity_metric() > other.min_quantity_metric() def match_key(m_obj): # type: (ProductDemand) -> object if order == match_order_choice.SCORE: return demand.match_score(m_obj)["score_overall"] elif order == match_order_choice.QUANTITY: return m_obj.quantity_left() elif order == match_order_choice.PRICE: return m_obj.price_metric().scaled_value() try: demand = ProductDemand.objects.select_related('uid__user_validate', 'qid__t3id__t2id__t1id', 'aid__cid__pid', 'pmid', 'wcid').get(in_use=True, id=id, uid=user) except ProductDemand.DoesNotExist: raise Error404("No such demand.") match_queryset = ProductDemand.objects.select_related( 'uid__user_validate', 'qid__t3id__t2id__t1id', 'aid__cid__pid', 'pmid', 'wcid').filter( in_use=True, # Must be in use match=True, qid=demand.qid, aid__cid__pid=demand.aid.cid.pid).exclude( uid__role=user.role # Exclude same role ).filter(end_time__gt=now(), ) # FIXME: Here we got a efficient issue, Every time user use this api, it will query the full set # of matched queryset. We must figure out how to fetch it by page, or ... cache it. matches = match_queryset.all() matches_list = [m for m in matches if confirm_satisfied(demand, m)] matches_list.sort(key=match_key, reverse=not asc) st, ed, n_pages = get_page_info_list( matches_list, count_per_page, page, index_error_excepiton=Error400("Page out of range")) # Set the match field if not demand.match: demand.match = True demand.save() # return sliced single page return demand, matches_list[st:ed], n_pages
def duration(self, value): self.end_time = now() + datetime.timedelta(days=value)
def expired_after_days(self): return max((self.end_time - now() + datetime.timedelta(days=0.5)).days, 0)
def is_expired(self): return self.end_time < now()