Beispiel #1
0
def execute(filters=None):
    is_reposting_item_valuation_in_progress()
    filters = frappe._dict(filters or {})
    include_uom = filters.get("include_uom")
    columns = get_columns()
    bin_list = get_bin_list(filters)
    item_map = get_item_map(filters.get("item_code"), include_uom)

    warehouse_company = {}
    data = []
    conversion_factors = []
    for bin in bin_list:
        item = item_map.get(bin.item_code)

        if not item:
            # likely an item that has reached its end of life
            continue

        # item = item_map.setdefault(bin.item_code, get_item(bin.item_code))
        company = warehouse_company.setdefault(
            bin.warehouse,
            frappe.db.get_value("Warehouse", bin.warehouse, "company"))

        if filters.brand and filters.brand != item.brand:
            continue

        elif filters.item_group and filters.item_group != item.item_group:
            continue

        elif filters.company and filters.company != company:
            continue

        re_order_level = re_order_qty = 0

        for d in item.get("reorder_levels"):
            if d.warehouse == bin.warehouse:
                re_order_level = d.warehouse_reorder_level
                re_order_qty = d.warehouse_reorder_qty

        shortage_qty = 0
        if (re_order_level
                or re_order_qty) and re_order_level > bin.projected_qty:
            shortage_qty = re_order_level - flt(bin.projected_qty)

        data.append([
            item.name, item.item_name, item.description, item.item_group,
            item.brand, bin.warehouse, item.stock_uom, bin.actual_qty,
            bin.planned_qty, bin.indented_qty, bin.ordered_qty,
            bin.reserved_qty, bin.reserved_qty_for_production,
            bin.reserved_qty_for_sub_contract, bin.projected_qty,
            re_order_level, re_order_qty, shortage_qty
        ])

        if include_uom:
            conversion_factors.append(item.conversion_factor)

    update_included_uom_in_report(columns, data, include_uom,
                                  conversion_factors)
    return columns, data
Beispiel #2
0
def execute(filters=None):
    is_reposting_item_valuation_in_progress()
    filters = frappe._dict(filters or {})
    columns = get_columns(filters)
    data = get_data(filters)
    chart = get_chart_data(columns)

    return columns, data, None, chart
Beispiel #3
0
def execute(filters=None):
    is_reposting_item_valuation_in_progress()
    include_uom = filters.get("include_uom")
    columns = get_columns()
    items = get_items(filters)
    sl_entries = get_stock_ledger_entries(filters, items)
    item_details = get_item_details(items, sl_entries, include_uom)
    opening_row = get_opening_balance(filters, columns, sl_entries)
    precision = cint(
        frappe.db.get_single_value("System Settings", "float_precision"))

    data = []
    conversion_factors = []
    if opening_row:
        data.append(opening_row)
        conversion_factors.append(0)

    actual_qty = stock_value = 0

    available_serial_nos = {}
    for sle in sl_entries:
        item_detail = item_details[sle.item_code]

        sle.update(item_detail)

        if filters.get("batch_no"):
            actual_qty += flt(sle.actual_qty, precision)
            stock_value += sle.stock_value_difference

            if sle.voucher_type == 'Stock Reconciliation' and not sle.actual_qty:
                actual_qty = sle.qty_after_transaction
                stock_value = sle.stock_value

            sle.update({
                "qty_after_transaction": actual_qty,
                "stock_value": stock_value
            })

        sle.update({
            "in_qty": max(sle.actual_qty, 0),
            "out_qty": min(sle.actual_qty, 0)
        })

        if sle.serial_no:
            update_available_serial_nos(available_serial_nos, sle)

        data.append(sle)

        if include_uom:
            conversion_factors.append(item_detail.conversion_factor)

    update_included_uom_in_report(columns, data, include_uom,
                                  conversion_factors)
    return columns, data
Beispiel #4
0
def execute(filters=None):
    is_reposting_item_valuation_in_progress()
    if not filters:
        filters = {}

    validate_filters(filters)

    from_date = filters.get('from_date')
    to_date = filters.get('to_date')

    if filters.get("company"):
        company_currency = erpnext.get_company_currency(filters.get("company"))
    else:
        company_currency = frappe.db.get_single_value(
            "Global Defaults", "default_currency")

    include_uom = filters.get("include_uom")
    columns = get_columns(filters)
    items = get_items(filters)
    sle = get_stock_ledger_entries(filters, items)

    if filters.get('show_stock_ageing_data'):
        filters['show_warehouse_wise_stock'] = True
        item_wise_fifo_queue = get_fifo_queue(filters, sle)

    # if no stock ledger entry found return
    if not sle:
        return columns, []

    iwb_map = get_item_warehouse_map(filters, sle)
    item_map = get_item_details(items, sle, filters)
    item_reorder_detail_map = get_item_reorder_details(item_map.keys())

    data = []
    conversion_factors = {}

    def _func(x): return x[1]

    for (company, item, warehouse) in sorted(iwb_map):
        if item_map.get(item):
            qty_dict = iwb_map[(company, item, warehouse)]
            item_reorder_level = 0
            item_reorder_qty = 0
            if item + warehouse in item_reorder_detail_map:
                item_reorder_level = item_reorder_detail_map[item +
                                                             warehouse]["warehouse_reorder_level"]
                item_reorder_qty = item_reorder_detail_map[item +
                                                           warehouse]["warehouse_reorder_qty"]

            report_data = {
                'currency': company_currency,
                'item_code': item,
                'warehouse': warehouse,
                'company': company,
                'reorder_level': item_reorder_level,
                'reorder_qty': item_reorder_qty,
            }
            report_data.update(item_map[item])
            report_data.update(qty_dict)

            if include_uom:
                conversion_factors.setdefault(
                    item, item_map[item].conversion_factor)

            if filters.get('show_stock_ageing_data'):
                fifo_queue = item_wise_fifo_queue[(
                    item, warehouse)].get('fifo_queue')

                stock_ageing_data = {
                    'average_age': 0,
                    'earliest_age': 0,
                    'latest_age': 0
                }
                if fifo_queue:
                    fifo_queue = sorted(filter(_func, fifo_queue), key=_func)
                    if not fifo_queue:
                        continue

                    stock_ageing_data['average_age'] = get_average_age(
                        fifo_queue, to_date)
                    stock_ageing_data['earliest_age'] = date_diff(
                        to_date, fifo_queue[0][1])
                    stock_ageing_data['latest_age'] = date_diff(
                        to_date, fifo_queue[-1][1])

                report_data.update(stock_ageing_data)

            data.append(report_data)

    add_additional_uom_columns(columns, data, include_uom, conversion_factors)
    return columns, data
def execute(filters=None):
    is_reposting_item_valuation_in_progress()
    if not filters: filters = {}

    validate_filters(filters)

    columns = get_columns(filters)

    items = get_items(filters)
    sle = get_stock_ledger_entries(filters, items)

    item_map = get_item_details(items, sle, filters)
    iwb_map = get_item_warehouse_map(filters, sle)
    warehouse_list = get_warehouse_list(filters)
    item_ageing = get_fifo_queue(filters)
    data = []
    item_balance = {}
    item_value = {}

    for (company, item, warehouse) in sorted(iwb_map):
        if not item_map.get(item): continue

        row = []
        qty_dict = iwb_map[(company, item, warehouse)]
        item_balance.setdefault((item, item_map[item]["item_group"]), [])
        total_stock_value = 0.00
        for wh in warehouse_list:
            row += [qty_dict.bal_qty] if wh.name in warehouse else [0.00]
            total_stock_value += qty_dict.bal_val if wh.name in warehouse else 0.00

        item_balance[(item, item_map[item]["item_group"])].append(row)
        item_value.setdefault((item, item_map[item]["item_group"]), [])
        item_value[(item,
                    item_map[item]["item_group"])].append(total_stock_value)

    # sum bal_qty by item
    for (item, item_group), wh_balance in iteritems(item_balance):
        if not item_ageing.get(item): continue

        total_stock_value = sum(item_value[(item, item_group)])
        row = [item, item_group, total_stock_value]

        fifo_queue = item_ageing[item]["fifo_queue"]
        average_age = 0.00
        if fifo_queue:
            average_age = get_average_age(fifo_queue, filters["to_date"])

        row += [average_age]

        bal_qty = [sum(bal_qty) for bal_qty in zip(*wh_balance)]
        total_qty = sum(bal_qty)
        if len(warehouse_list) > 1:
            row += [total_qty]
        row += bal_qty

        if total_qty > 0:
            data.append(row)
        elif not filters.get("filter_total_zero_qty"):
            data.append(row)
    add_warehouse_column(columns, warehouse_list)
    return columns, data
Beispiel #6
0
def execute(filters: Optional[StockBalanceFilter] = None):
    is_reposting_item_valuation_in_progress()
    if not filters:
        filters = {}

    if filters.get("company"):
        company_currency = erpnext.get_company_currency(filters.get("company"))
    else:
        company_currency = frappe.db.get_single_value("Global Defaults",
                                                      "default_currency")

    include_uom = filters.get("include_uom")
    columns = get_columns(filters)
    items = get_items(filters)
    sle = get_stock_ledger_entries(filters, items)

    if filters.get("show_stock_ageing_data"):
        filters["show_warehouse_wise_stock"] = True
        item_wise_fifo_queue = FIFOSlots(filters, sle).generate()

    # if no stock ledger entry found return
    if not sle:
        return columns, []

    iwb_map = get_item_warehouse_map(filters, sle)
    item_map = get_item_details(items, sle, filters)
    item_reorder_detail_map = get_item_reorder_details(item_map.keys())

    data = []
    conversion_factors = {}

    _func = itemgetter(1)

    to_date = filters.get("to_date")
    for (company, item, warehouse) in sorted(iwb_map):
        if item_map.get(item):
            qty_dict = iwb_map[(company, item, warehouse)]
            item_reorder_level = 0
            item_reorder_qty = 0
            if item + warehouse in item_reorder_detail_map:
                item_reorder_level = item_reorder_detail_map[
                    item + warehouse]["warehouse_reorder_level"]
                item_reorder_qty = item_reorder_detail_map[
                    item + warehouse]["warehouse_reorder_qty"]

            report_data = {
                "currency": company_currency,
                "item_code": item,
                "warehouse": warehouse,
                "company": company,
                "reorder_level": item_reorder_level,
                "reorder_qty": item_reorder_qty,
            }
            report_data.update(item_map[item])
            report_data.update(qty_dict)

            if include_uom:
                conversion_factors.setdefault(item,
                                              item_map[item].conversion_factor)

            if filters.get("show_stock_ageing_data"):
                fifo_queue = item_wise_fifo_queue[(
                    item, warehouse)].get("fifo_queue")

                stock_ageing_data = {
                    "average_age": 0,
                    "earliest_age": 0,
                    "latest_age": 0
                }
                if fifo_queue:
                    fifo_queue = sorted(filter(_func, fifo_queue), key=_func)
                    if not fifo_queue:
                        continue

                    stock_ageing_data["average_age"] = get_average_age(
                        fifo_queue, to_date)
                    stock_ageing_data["earliest_age"] = date_diff(
                        to_date, fifo_queue[0][1])
                    stock_ageing_data["latest_age"] = date_diff(
                        to_date, fifo_queue[-1][1])

                report_data.update(stock_ageing_data)

            data.append(report_data)

    add_additional_uom_columns(columns, data, include_uom, conversion_factors)
    return columns, data