def create_leave_allocation(employee, leave_type, new_leaves_allocated, leave_type_details, leave_period, carry_forward, date_of_joining): ''' Creates leave allocation for the given employee in the provided leave period ''' if carry_forward and not leave_type_details.get(leave_type).is_carry_forward: carry_forward = 0 # Calculate leaves at pro-rata basis for employees joining after the beginning of the given leave period if getdate(date_of_joining) > getdate(leave_period.from_date): remaining_period = ((date_diff(leave_period.to_date, date_of_joining) + 1) / (date_diff(leave_period.to_date, leave_period.from_date) + 1)) new_leaves_allocated = ceil(new_leaves_allocated * remaining_period) # Earned Leaves and Compensatory Leaves are allocated by scheduler, initially allocate 0 if leave_type_details.get(leave_type).is_earned_leave == 1 or leave_type_details.get(leave_type).is_compensatory == 1: new_leaves_allocated = 0 allocation = frappe.get_doc(dict( doctype="Leave Allocation", employee=employee, leave_type=leave_type, from_date=leave_period.from_date, to_date=leave_period.to_date, new_leaves_allocated=new_leaves_allocated, leave_period=leave_period.name, carry_forward=carry_forward )) allocation.save(ignore_permissions = True) allocation.submit() return allocation.name
def get_material_request_items(row, sales_order, company, ignore_existing_ordered_qty, warehouse, bin_dict): total_qty = row['qty'] required_qty = 0 if ignore_existing_ordered_qty or bin_dict.get("projected_qty", 0) < 0: required_qty = total_qty elif total_qty > bin_dict.get("projected_qty", 0): required_qty = total_qty - bin_dict.get("projected_qty", 0) if required_qty > 0 and required_qty < row['min_order_qty']: required_qty = row['min_order_qty'] item_group_defaults = get_item_group_defaults(row.item_code, company) if not row['purchase_uom']: row['purchase_uom'] = row['stock_uom'] if row['purchase_uom'] != row['stock_uom']: if not row['conversion_factor']: frappe.throw( _("UOM Conversion factor ({0} -> {1}) not found for item: {2}" ).format(row['purchase_uom'], row['stock_uom'], row.item_code)) required_qty = required_qty / row['conversion_factor'] if frappe.db.get_value("UOM", row['purchase_uom'], "must_be_whole_number"): required_qty = ceil(required_qty) if required_qty > 0: return { 'item_code': row.item_code, 'item_name': row.item_name, 'quantity': required_qty, 'description': row.description, 'stock_uom': row.get("stock_uom"), 'warehouse': warehouse or row.get('source_warehouse') or row.get('default_warehouse') or item_group_defaults.get("default_warehouse"), 'actual_qty': bin_dict.get("actual_qty", 0), 'projected_qty': bin_dict.get("projected_qty", 0), 'min_order_qty': row['min_order_qty'], 'material_request_type': row.get("default_material_request_type"), 'sales_order': sales_order, 'description': row.get("description"), 'uom': row.get("purchase_uom") or row.get("stock_uom") }
def get_materials_from_other_locations(item, warehouses, new_mr_items, company): from erpnext.stock.doctype.pick_list.pick_list import get_available_item_locations locations = get_available_item_locations(item.get("item_code"), warehouses, item.get("quantity"), company, ignore_validation=True) required_qty = item.get("quantity") # get available material by transferring to production warehouse for d in locations: if required_qty <= 0: return new_dict = copy.deepcopy(item) quantity = required_qty if d.get("qty") > required_qty else d.get( "qty") new_dict.update({ "quantity": quantity, "material_request_type": "Material Transfer", "uom": new_dict.get( "stock_uom"), # internal transfer should be in stock UOM "from_warehouse": d.get("warehouse"), }) required_qty -= quantity new_mr_items.append(new_dict) # raise purchase request for remaining qty if required_qty: stock_uom, purchase_uom = frappe.db.get_value( "Item", item["item_code"], ["stock_uom", "purchase_uom"]) if purchase_uom != stock_uom and purchase_uom == item["uom"]: conversion_factor = get_uom_conversion_factor( item["item_code"], item["uom"]) if not (conversion_factor or frappe.flags.show_qty_in_stock_uom): frappe.throw( _("UOM Conversion factor ({0} -> {1}) not found for item: {2}" ).format(purchase_uom, stock_uom, item["item_code"])) required_qty = required_qty / conversion_factor if frappe.db.get_value("UOM", purchase_uom, "must_be_whole_number"): required_qty = ceil(required_qty) item["quantity"] = required_qty new_mr_items.append(item)
def test_ceil(self): from decimal import Decimal self.assertEqual(ceil(2), 2) self.assertEqual(ceil(12.32904), 13) self.assertEqual(ceil(22.7330), 23) self.assertEqual(ceil('24.7'), 25) self.assertEqual(ceil('26.7'), 27) self.assertEqual(ceil(Decimal(29.45)), 30)
def test_ceil(self): from decimal import Decimal self.assertEqual(ceil(2), 2 ) self.assertEqual(ceil(12.32904), 13) self.assertEqual(ceil(22.7330), 23) self.assertEqual(ceil('24.7'), 25) self.assertEqual(ceil('26.7'), 27) self.assertEqual(ceil(Decimal(29.45)), 30)
def get_material_request_items(row, sales_order, company, ignore_existing_ordered_qty, warehouse): total_qty = row['qty'] projected_qty, actual_qty = get_bin_details(row) requested_qty = 0 if ignore_existing_ordered_qty: requested_qty = total_qty elif total_qty > projected_qty: requested_qty = total_qty - projected_qty if requested_qty > 0 and requested_qty < row['min_order_qty']: requested_qty = row['min_order_qty'] item_group_defaults = get_item_group_defaults(row.item_code, company) if not row['purchase_uom']: row['purchase_uom'] = row['stock_uom'] if row['purchase_uom'] != row['stock_uom']: if not row['conversion_factor']: frappe.throw(_("UOM Conversion factor ({0} -> {1}) not found for item: {2}") .format(row['purchase_uom'], row['stock_uom'], row.item_code)) requested_qty = requested_qty / row['conversion_factor'] if frappe.db.get_value("UOM", row['purchase_uom'], "must_be_whole_number"): requested_qty = ceil(requested_qty) if requested_qty > 0: return { 'item_code': row.item_code, 'item_name': row.item_name, 'quantity': requested_qty, 'warehouse': warehouse or row.get('source_warehouse') \ or row.get('default_warehouse') or item_group_defaults.get("default_warehouse"), 'actual_qty': actual_qty, 'min_order_qty': row['min_order_qty'], 'sales_order': sales_order }
def get_material_request_items(row, sales_order, company, ignore_existing_ordered_qty, include_safety_stock, warehouse, bin_dict): total_qty = row["qty"] required_qty = 0 if ignore_existing_ordered_qty or bin_dict.get("projected_qty", 0) < 0: required_qty = total_qty elif total_qty > bin_dict.get("projected_qty", 0): required_qty = total_qty - bin_dict.get("projected_qty", 0) if required_qty > 0 and required_qty < row["min_order_qty"]: required_qty = row["min_order_qty"] item_group_defaults = get_item_group_defaults(row.item_code, company) if not row["purchase_uom"]: row["purchase_uom"] = row["stock_uom"] if row["purchase_uom"] != row["stock_uom"]: if not (row["conversion_factor"] or frappe.flags.show_qty_in_stock_uom): frappe.throw( _("UOM Conversion factor ({0} -> {1}) not found for item: {2}" ).format(row["purchase_uom"], row["stock_uom"], row.item_code)) required_qty = required_qty / row["conversion_factor"] if frappe.db.get_value("UOM", row["purchase_uom"], "must_be_whole_number"): required_qty = ceil(required_qty) if include_safety_stock: required_qty += flt(row["safety_stock"]) if required_qty > 0: return { "item_code": row.item_code, "item_name": row.item_name, "quantity": required_qty, "required_bom_qty": total_qty, "stock_uom": row.get("stock_uom"), "warehouse": warehouse or row.get("source_warehouse") or row.get("default_warehouse") or item_group_defaults.get("default_warehouse"), "safety_stock": row.safety_stock, "actual_qty": bin_dict.get("actual_qty", 0), "projected_qty": bin_dict.get("projected_qty", 0), "ordered_qty": bin_dict.get("ordered_qty", 0), "reserved_qty_for_production": bin_dict.get("reserved_qty_for_production", 0), "min_order_qty": row["min_order_qty"], "material_request_type": row.get("default_material_request_type"), "sales_order": sales_order, "description": row.get("description"), "uom": row.get("purchase_uom") or row.get("stock_uom"), }