Ejemplo n.º 1
0
def sync_product_stock(domain, endpoint, facility, checkpoint, date, limit=100, offset=0):
    has_next = True
    next_url = ""
    while has_next:
        supply_point = facility
        case = SupplyPointCase.view('hqcase/by_domain_external_id',
                                    key=[domain, str(supply_point)],
                                    reduce=False,
                                    include_docs=True,
                                    limit=1).first()
        meta, product_stocks = endpoint.get_productstocks(
            next_url_params=next_url,
            limit=limit,
            offset=offset,
            filters=dict(supply_point=supply_point, last_modified__gte=date)
        )
        save_stock_data_checkpoint(checkpoint,
                                   'product_stock',
                                   meta.get('limit') or limit,
                                   meta.get('offset') or offset,
                                   date, facility, True)
        for product_stock in product_stocks:
            if case:
                product = Product.get_by_code(domain, product_stock.product)
                try:
                    stock_state = StockState.objects.get(section_id='stock',
                                                         case_id=case._id,
                                                         product_id=product._id)
                    stock_state.last_modified_date = product_stock.last_modified
                    stock_state.stock_on_hand = product_stock.quantity or 0
                except StockState.DoesNotExist:
                    stock_state = StockState(section_id='stock',
                                             case_id=case._id,
                                             product_id=product._id,
                                             stock_on_hand=product_stock.quantity or 0,
                                             last_modified_date=product_stock.last_modified,
                                             sql_product=SQLProduct.objects.get(product_id=product._id))

                if product_stock.auto_monthly_consumption:
                    stock_state.daily_consumption = product_stock.auto_monthly_consumption / DAYS_IN_MONTH
                else:
                    stock_state.daily_consumption = None
                stock_state.save()

        if not meta.get('next', False):
            has_next = False
        else:
            next_url = meta['next'].split('?')[1]
Ejemplo n.º 2
0
def get_product_stock(domain, endpoint, facilities):
    for facility in facilities:
        has_next = True
        next_url = ""
        while has_next:
            meta, product_stocks = endpoint.get_productstocks(next_url_params=next_url,
                                                              filters=dict(supply_point=facility))
            for product_stock in product_stocks:
                case = SupplyPointCase.view('hqcase/by_domain_external_id',
                                            key=[domain, str(product_stock.supply_point)],
                                            reduce=False,
                                            include_docs=True,
                                            limit=1).first()
                product = Product.get_by_code(domain, product_stock.product)
                try:
                    stock_state = StockState.objects.get(section_id='stock',
                                                         case_id=case._id,
                                                         product_id=product._id)
                except StockState.DoesNotExist:
                    stock_state = StockState(section_id='stock',
                                             case_id=case._id,
                                             product_id=product._id,
                                             stock_on_hand=product_stock.quantity or 0,
                                             last_modified_date=product_stock.last_modified,
                                             sql_product=SQLProduct.objects.get(product_id=product._id))

                if product_stock.auto_monthly_consumption:
                    stock_state.daily_consumption = product_stock.auto_monthly_consumption / DAYS_IN_MONTH
                elif product_stock.use_auto_consumption is False:
                    stock_state.daily_consumption = product_stock.manual_monthly_consumption / DAYS_IN_MONTH
                else:
                    stock_state.daily_consumption = None

                stock_state.save()

            if not meta.get('next', False):
                has_next = False
            else:
                next_url = meta['next'].split('?')[1]
Ejemplo n.º 3
0
def update_stock_state_for_transaction(instance):
    from corehq.apps.commtrack.models import StockState
    from corehq.apps.locations.models import SQLLocation
    from corehq.apps.products.models import SQLProduct

    # todo: in the worst case, this function makes
    # - three calls to couch (for the case, domain, and commtrack config)
    # - four postgres queries (transacitons, product, location, and state)
    # - one postgres write (to save the state)
    # and that doesn't even include the consumption calc, which can do a whole
    # bunch more work and hit the database.
    sql_product = SQLProduct.objects.get(product_id=instance.product_id)
    try:
        domain_name = instance.domain
    except AttributeError:
        domain_name = sql_product.domain

    domain = Domain.get_by_name(domain_name)

    try:
        sql_location = SQLLocation.objects.get(
            supply_point_id=instance.case_id)
    except SQLLocation.DoesNotExist:
        sql_location = None

    try:
        state = StockState.include_archived.get(
            section_id=instance.section_id,
            case_id=instance.case_id,
            product_id=instance.product_id,
        )
    except StockState.DoesNotExist:
        state = StockState(
            section_id=instance.section_id,
            case_id=instance.case_id,
            product_id=instance.product_id,
            sql_product=sql_product,
            sql_location=sql_location,
        )

    # we may not be saving the latest transaction so make sure we use that
    # todo: this should change to server date
    latest_transaction = StockTransaction.latest(
        case_id=instance.case_id,
        section_id=instance.section_id,
        product_id=instance.product_id)
    if latest_transaction != instance:
        logging.warning(
            'Just fired signal for a stale stock transaction. Domain: {}, instance: {},latest was {}'
            .format(domain_name, instance, latest_transaction))
        instance = latest_transaction
    state.last_modified_date = instance.report.date
    state.stock_on_hand = instance.stock_on_hand

    if domain and domain.commtrack_settings:
        consumption_calc = domain.commtrack_settings.get_consumption_config()
    else:
        consumption_calc = None

    state.daily_consumption = compute_daily_consumption(
        instance.case_id, instance.product_id, instance.report.date, 'stock',
        consumption_calc)
    # so you don't have to look it up again in the signal receivers
    if domain:
        state.domain = domain.name
    state.save()
Ejemplo n.º 4
0
def update_stock_state_for_transaction(instance):
    from corehq.apps.commtrack.models import StockState
    from corehq.apps.locations.models import SQLLocation
    from corehq.apps.products.models import SQLProduct

    # todo: in the worst case, this function makes
    # - three calls to couch (for the case, domain, and commtrack config)
    # - four postgres queries (transacitons, product, location, and state)
    # - one postgres write (to save the state)
    # and that doesn't even include the consumption calc, which can do a whole
    # bunch more work and hit the database.
    sql_product = SQLProduct.objects.get(product_id=instance.product_id)
    try:
        domain_name = instance.domain
    except AttributeError:
        domain_name = sql_product.domain

    domain = Domain.get_by_name(domain_name)

    try:
        sql_location = SQLLocation.objects.get(supply_point_id=instance.case_id)
    except SQLLocation.DoesNotExist:
        sql_location = None

    try:
        state = StockState.include_archived.get(
            section_id=instance.section_id,
            case_id=instance.case_id,
            product_id=instance.product_id,
        )
    except StockState.DoesNotExist:
        state = StockState(
            section_id=instance.section_id,
            case_id=instance.case_id,
            product_id=instance.product_id,
            sql_product=sql_product,
            sql_location=sql_location,
        )

    # we may not be saving the latest transaction so make sure we use that
    # todo: this should change to server date
    latest_transaction = StockTransaction.latest(
        case_id=instance.case_id,
        section_id=instance.section_id,
        product_id=instance.product_id
    )
    if latest_transaction != instance:
        logging.warning(
            'Just fired signal for a stale stock transaction. Domain: {}, instance: {},latest was {}'.format(
                domain_name, instance, latest_transaction
            )
        )
        instance = latest_transaction
    state.last_modified_date = instance.report.date
    state.stock_on_hand = instance.stock_on_hand

    if domain and domain.commtrack_settings:
        consumption_calc = domain.commtrack_settings.get_consumption_config()
    else:
        consumption_calc = None

    state.daily_consumption = compute_daily_consumption(
        domain_name,
        instance.case_id,
        instance.product_id,
        instance.report.date,
        'stock',
        consumption_calc
    )
    # so you don't have to look it up again in the signal receivers
    if domain:
        state.domain = domain.name
    state.save()