def get_asset_account(account_name, asset=None, asset_category=None, company=None): account = None if asset: account = get_asset_category_account(account_name, asset=asset, asset_category=asset_category, company=company) if not asset and not account: account = get_asset_category_account(account_name, asset_category=asset_category, company=company) if not account: account = frappe.get_cached_value('Company', company, account_name) if not account: if not asset_category: frappe.throw( _("Set {0} in company {1}").format( account_name.replace('_', ' ').title(), company)) else: frappe.throw( _("Set {0} in asset category {1} or company {2}").format( account_name.replace('_', ' ').title(), asset_category, company)) return account
def make_purchase_invoice(asset, item_code, gross_purchase_amount, company, posting_date): pi = frappe.new_doc("Purchase Invoice") pi.company = company pi.currency = frappe.get_cached_value('Company', company, "default_currency") pi.set_posting_time = 1 pi.posting_date = posting_date pi.append( "items", { "item_code": item_code, "is_fixed_asset": 1, "asset": asset, "expense_account": get_asset_category_account(asset, 'fixed_asset_account'), "qty": 1, "price_list_rate": gross_purchase_amount, "rate": gross_purchase_amount }) pi.set_missing_values() return pi
def make_gl_entries(self): gl_entries = [] if ((self.purchase_receipt or (self.purchase_invoice and frappe.db.get_value('Purchase Invoice', self.purchase_invoice, 'update_stock'))) and self.purchase_receipt_amount and self.available_for_use_date <= nowdate()): fixed_aseet_account = get_asset_category_account(self.name, 'fixed_asset_account', asset_category = self.asset_category, company = self.company) cwip_account = get_asset_account("capital_work_in_progress_account", self.name, self.asset_category, self.company) gl_entries.append(self.get_gl_dict({ "account": cwip_account, "against": fixed_aseet_account, "remarks": self.get("remarks") or _("Accounting Entry for Asset"), "posting_date": self.available_for_use_date, "credit": self.purchase_receipt_amount, "credit_in_account_currency": self.purchase_receipt_amount })) gl_entries.append(self.get_gl_dict({ "account": fixed_aseet_account, "against": cwip_account, "remarks": self.get("remarks") or _("Accounting Entry for Asset"), "posting_date": self.available_for_use_date, "debit": self.purchase_receipt_amount, "debit_in_account_currency": self.purchase_receipt_amount })) if gl_entries: from erpnext.accounts.general_ledger import make_gl_entries make_gl_entries(gl_entries) self.db_set('booked_fixed_asset', 1)
def add_lcv_gl_entries(self, item, gl_entries): expenses_included_in_asset_valuation = self.get_company_default("expenses_included_in_asset_valuation") if not is_cwip_accounting_enabled(item.asset_category): asset_account = get_asset_category_account(asset_category=item.asset_category, \ fieldname='fixed_asset_account', company=self.company) else: # This returns company's default cwip account asset_account = get_asset_account("capital_work_in_progress_account", company=self.company) gl_entries.append(self.get_gl_dict({ "account": expenses_included_in_asset_valuation, "against": asset_account, "cost_center": item.cost_center, "remarks": self.get("remarks") or _("Accounting Entry for Stock"), "credit": flt(item.landed_cost_voucher_amount), "project": item.project }, item=item)) gl_entries.append(self.get_gl_dict({ "account": asset_account, "against": expenses_included_in_asset_valuation, "cost_center": item.cost_center, "remarks": self.get("remarks") or _("Accounting Entry for Stock"), "debit": flt(item.landed_cost_voucher_amount), "project": item.project }, item=item))
def add_lcv_gl_entries(self, item, gl_entries): expenses_included_in_asset_valuation = self.get_company_default("expenses_included_in_asset_valuation") if not is_cwip_accounting_enabled(item.asset_category): asset_account = get_asset_category_account(asset_category=item.asset_category, \ fieldname='fixed_asset_account', company=self.company) else: # This returns company's default cwip account asset_account = get_asset_account("capital_work_in_progress_account", company=self.company) remarks = self.get("remarks") or _("Accounting Entry for Stock") self.add_gl_entry( gl_entries=gl_entries, account=expenses_included_in_asset_valuation, cost_center=item.cost_center, debit=0.0, credit=flt(item.landed_cost_voucher_amount), remarks=remarks, against_account=asset_account, project=item.project, item=item) self.add_gl_entry( gl_entries=gl_entries, account=asset_account, cost_center=item.cost_center, debit=flt(item.landed_cost_voucher_amount), credit=0.0, remarks=remarks, against_account=expenses_included_in_asset_valuation, project=item.project, item=item)
def get_item_default_expense_account(item_code): item_defaults = get_item_defaults(item_code, frappe.db.get_single_value("Global Defaults", "default_company")) item_group_defaults = get_item_group_defaults(item_code, frappe.db.get_single_value("Global Defaults", "default_company")) expense_account = get_asset_category_account(fieldname = "fixed_asset_account", item = item_code, company= frappe.db.get_single_value("Global Defaults", "default_company")) if not expense_account: expense_account = item_defaults.get("expense_account") or item_group_defaults.get("expense_account") or get_brand_defaults(item_code,frappe.db.get_single_value("Global Defaults", "default_company") ) frappe.response["expense_account"] = expense_account frappe.response["company"]= frappe.db.get_single_value("Global Defaults", "default_company")
def get_asset_accounts(self): fixed_asset_account = get_asset_category_account('fixed_asset_account', asset=self.name, asset_category = self.asset_category, company = self.company) cwip_account = get_asset_account("capital_work_in_progress_account", self.name, self.asset_category, self.company) return fixed_asset_account, cwip_account
def set_expense_account(self, for_validate=False): auto_accounting_for_stock = erpnext.is_perpetual_inventory_enabled(self.company) if auto_accounting_for_stock: stock_not_billed_account = self.get_company_default("stock_received_but_not_billed") stock_items = self.get_stock_items() asset_items = [d.is_fixed_asset for d in self.items if d.is_fixed_asset] if len(asset_items) > 0: asset_received_but_not_billed = self.get_company_default("asset_received_but_not_billed") if self.update_stock: self.validate_item_code() self.validate_warehouse() if auto_accounting_for_stock: warehouse_account = get_warehouse_account_map(self.company) for item in self.get("items"): # in case of auto inventory accounting, # expense account is always "Stock Received But Not Billed" for a stock item # except opening entry, drop-ship entry and fixed asset items if item.item_code: asset_category = frappe.get_cached_value("Item", item.item_code, "asset_category") if auto_accounting_for_stock and item.item_code in stock_items \ and self.is_opening == 'No' and not item.is_fixed_asset \ and (not item.po_detail or not frappe.db.get_value("Purchase Order Item", item.po_detail, "delivered_by_supplier")): if self.update_stock and (not item.from_warehouse): item.expense_account = warehouse_account[item.warehouse]["account"] else: # check if 'Stock Received But Not Billed' account is credited in Purchase receipt or not if item.purchase_receipt: negative_expense_booked_in_pr = frappe.db.sql("""select name from `tabGL Entry` where voucher_type='Purchase Receipt' and voucher_no=%s and account = %s""", (item.purchase_receipt, stock_not_billed_account)) if negative_expense_booked_in_pr: item.expense_account = stock_not_billed_account else: # If no purchase receipt present then book expense in 'Stock Received But Not Billed' # This is done in cases when Purchase Invoice is created before Purchase Receipt item.expense_account = stock_not_billed_account elif item.is_fixed_asset and not is_cwip_accounting_enabled(asset_category): item.expense_account = get_asset_category_account('fixed_asset_account', item=item.item_code, company = self.company) elif item.is_fixed_asset and item.pr_detail: item.expense_account = asset_received_but_not_billed elif not item.expense_account and for_validate: throw(_("Expense account is mandatory for item {0}").format(item.item_code or item.item_name))
def get_asset_account(account_name, asset=None, asset_category=None, company=None): account = None if asset: account = get_asset_category_account(asset, account_name, asset_category = asset_category, company = company) if not account: account = frappe.get_cached_value('Company', company, account_name) if not account: frappe.throw(_("Set {0} in asset category {1} or company {2}") .format(account_name.replace('_', ' ').title(), asset_category, company)) return account
def get_fixed_asset_account(self): fixed_asset_account = get_asset_category_account( "fixed_asset_account", None, self.name, None, self.asset_category, self.company ) if not fixed_asset_account: frappe.throw( _("Set {0} in asset category {1} for company {2}").format( frappe.bold("Fixed Asset Account"), frappe.bold(self.asset_category), frappe.bold(self.company), ), title=_("Account not Found"), ) return fixed_asset_account
def make_purchase_invoice(asset, item_code, gross_purchase_amount, company, posting_date): pi = frappe.new_doc("Purchase Invoice") pi.company = company pi.currency = frappe.get_cached_value('Company', company, "default_currency") pi.set_posting_time = 1 pi.posting_date = posting_date pi.append("items", { "item_code": item_code, "is_fixed_asset": 1, "asset": asset, "expense_account": get_asset_category_account(asset, 'fixed_asset_account'), "qty": 1, "price_list_rate": gross_purchase_amount, "rate": gross_purchase_amount }) pi.set_missing_values() return pi
def set_expense_account(self, for_validate=False): auto_accounting_for_stock = erpnext.is_perpetual_inventory_enabled(self.company) if auto_accounting_for_stock: stock_not_billed_account = self.get_company_default("stock_received_but_not_billed") stock_items = self.get_stock_items() asset_items = [d.is_fixed_asset for d in self.items if d.is_fixed_asset] if len(asset_items) > 0: asset_received_but_not_billed = self.get_company_default("asset_received_but_not_billed") if self.update_stock: self.validate_item_code() self.validate_warehouse() if auto_accounting_for_stock: warehouse_account = get_warehouse_account_map(self.company) for item in self.get("items"): # in case of auto inventory accounting, # expense account is always "Stock Received But Not Billed" for a stock item # except epening entry, drop-ship entry and fixed asset items if auto_accounting_for_stock and item.item_code in stock_items \ and self.is_opening == 'No' and not item.is_fixed_asset \ and (not item.po_detail or not frappe.db.get_value("Purchase Order Item", item.po_detail, "delivered_by_supplier")): if self.update_stock: item.expense_account = warehouse_account[item.warehouse]["account"] else: item.expense_account = stock_not_billed_account elif item.is_fixed_asset and is_cwip_accounting_disabled(): if not item.asset: frappe.throw(_("Row {0}: asset is required for item {1}") .format(item.idx, item.item_code)) item.expense_account = get_asset_category_account(item.asset, 'fixed_asset_account', company = self.company) elif item.is_fixed_asset and item.pr_detail: item.expense_account = asset_received_but_not_billed elif not item.expense_account and for_validate: throw(_("Expense account is mandatory for item {0}").format(item.item_code or item.item_name))
def get_basic_details(args, item, overwrite_warehouse=True): """ :param args: { "item_code": "", "warehouse": None, "customer": "", "conversion_rate": 1.0, "selling_price_list": None, "price_list_currency": None, "price_list_uom_dependant": None, "plc_conversion_rate": 1.0, "doctype": "", "name": "", "supplier": None, "transaction_date": None, "conversion_rate": 1.0, "buying_price_list": None, "is_subcontracted": "Yes" / "No", "ignore_pricing_rule": 0/1 "project": "", barcode: "", serial_no: "", currency: "", update_stock: "", price_list: "", company: "", order_type: "", is_pos: "", project: "", qty: "", stock_qty: "", conversion_factor: "", against_blanket_order: 0/1 } :param item: `item_code` of Item object :return: frappe._dict """ if not item: item = frappe.get_doc("Item", args.get("item_code")) if item.variant_of: item.update_template_tables() item_defaults = get_item_defaults(item.name, args.company) item_group_defaults = get_item_group_defaults(item.name, args.company) brand_defaults = get_brand_defaults(item.name, args.company) defaults = frappe._dict({ 'item_defaults': item_defaults, 'item_group_defaults': item_group_defaults, 'brand_defaults': brand_defaults }) warehouse = get_item_warehouse(item, args, overwrite_warehouse, defaults) if args.get('doctype') == "Material Request" and not args.get( 'material_request_type'): args['material_request_type'] = frappe.db.get_value( 'Material Request', args.get('name'), 'material_request_type', cache=True) expense_account = None if args.get('doctype') == 'Purchase Invoice' and item.is_fixed_asset: from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account expense_account = get_asset_category_account( fieldname="fixed_asset_account", item=args.item_code, company=args.company) #Set the UOM to the Default Sales UOM or Default Purchase UOM if configured in the Item Master if not args.get('uom'): if args.get('doctype') in sales_doctypes: args.uom = item.sales_uom if item.sales_uom else item.stock_uom elif (args.get('doctype') in ['Purchase Order', 'Purchase Receipt', 'Purchase Invoice']) or \ (args.get('doctype') == 'Material Request' and args.get('material_request_type') == 'Purchase'): args.uom = item.purchase_uom if item.purchase_uom else item.stock_uom else: args.uom = item.stock_uom out = frappe._dict({ "item_code": item.name, "item_name": item.item_name, "description": cstr(item.description).strip(), "image": cstr(item.image).strip(), "warehouse": warehouse, "income_account": get_default_income_account(args, item_defaults, item_group_defaults, brand_defaults), "expense_account": expense_account or get_default_expense_account( args, item_defaults, item_group_defaults, brand_defaults), "cost_center": get_default_cost_center(args, item_defaults, item_group_defaults, brand_defaults), 'has_serial_no': item.has_serial_no, 'has_batch_no': item.has_batch_no, "batch_no": args.get("batch_no"), "uom": args.uom, "min_order_qty": flt(item.min_order_qty) if args.doctype == "Material Request" else "", "qty": flt(args.qty) or 1.0, "stock_qty": flt(args.qty) or 1.0, "price_list_rate": 0.0, "base_price_list_rate": 0.0, "rate": 0.0, "base_rate": 0.0, "amount": 0.0, "base_amount": 0.0, "net_rate": 0.0, "net_amount": 0.0, "discount_percentage": 0.0, "supplier": get_default_supplier(args, item_defaults, item_group_defaults, brand_defaults), "update_stock": args.get("update_stock") if args.get('doctype') in ['Sales Invoice', 'Purchase Invoice'] else 0, "delivered_by_supplier": item.delivered_by_supplier if args.get("doctype") in ["Sales Order", "Sales Invoice"] else 0, "is_fixed_asset": item.is_fixed_asset, "weight_per_unit": item.weight_per_unit, "weight_uom": item.weight_uom, "last_purchase_rate": item.last_purchase_rate if args.get("doctype") in ["Purchase Order"] else 0, "transaction_date": args.get("transaction_date"), "against_blanket_order": args.get("against_blanket_order"), "bom_no": item.get("default_bom") }) if item.get("enable_deferred_revenue") or item.get( "enable_deferred_expense"): out.update(calculate_service_end_date(args, item)) # calculate conversion factor if item.stock_uom == args.uom: out.conversion_factor = 1.0 else: out.conversion_factor = args.conversion_factor or \ get_conversion_factor(item.name, args.uom).get("conversion_factor") args.conversion_factor = out.conversion_factor out.stock_qty = out.qty * out.conversion_factor # calculate last purchase rate if args.get('doctype') in purchase_doctypes: from erpnext.buying.doctype.purchase_order.purchase_order import item_last_purchase_rate out.last_purchase_rate = item_last_purchase_rate( args.name, args.conversion_rate, item.name, out.conversion_factor) # if default specified in item is for another company, fetch from company for d in [["Account", "income_account", "default_income_account"], ["Account", "expense_account", "default_expense_account"], ["Cost Center", "cost_center", "cost_center"], ["Warehouse", "warehouse", ""]]: if not out[d[1]]: out[d[1]] = frappe.get_cached_value('Company', args.company, d[2]) if d[2] else None for fieldname in ("item_name", "item_group", "barcodes", "brand", "stock_uom"): out[fieldname] = item.get(fieldname) if args.get("manufacturer"): part_no = get_item_manufacturer_part_no(args.get("item_code"), args.get("manufacturer")) if part_no: out["manufacturer_part_no"] = part_no else: out["manufacturer_part_no"] = None out["manufacturer"] = None else: data = frappe.get_value( "Item", item.name, ["default_item_manufacturer", "default_manufacturer_part_no"], as_dict=1) if data: out.update({ "manufacturer": data.default_item_manufacturer, "manufacturer_part_no": data.default_manufacturer_part_no }) child_doctype = args.doctype + ' Item' meta = frappe.get_meta(child_doctype) if meta.get_field("barcode"): update_barcode_value(out) return out
def get_asset_gl_entry(self, gl_entries, expenses_included_in_valuation=None): arbnb_account, cwip_account = None, None cwip_disabled = is_cwip_accounting_disabled() if not expenses_included_in_valuation: expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation") for d in self.get("items"): if d.is_fixed_asset and not (arbnb_account and cwip_account): arbnb_account = self.get_company_default("asset_received_but_not_billed") # CWIP entry cwip_account = get_asset_account("capital_work_in_progress_account", d.asset, company = self.company) if d.is_fixed_asset and not cwip_disabled: asset_amount = flt(d.net_amount) + flt(d.item_tax_amount/self.conversion_rate) base_asset_amount = flt(d.base_net_amount + d.item_tax_amount) cwip_account_currency = get_account_currency(cwip_account) gl_entries.append(self.get_gl_dict({ "account": cwip_account, "against": arbnb_account, "cost_center": d.cost_center, "remarks": self.get("remarks") or _("Accounting Entry for Asset"), "debit": base_asset_amount, "debit_in_account_currency": (base_asset_amount if cwip_account_currency == self.company_currency else asset_amount) }, item=d)) # Asset received but not billed asset_rbnb_currency = get_account_currency(arbnb_account) gl_entries.append(self.get_gl_dict({ "account": arbnb_account, "against": cwip_account, "cost_center": d.cost_center, "remarks": self.get("remarks") or _("Accounting Entry for Asset"), "credit": base_asset_amount, "credit_in_account_currency": (base_asset_amount if asset_rbnb_currency == self.company_currency else asset_amount) }, item=d)) if d.is_fixed_asset and flt(d.landed_cost_voucher_amount): asset_account = (get_asset_category_account(d.asset, 'fixed_asset_account', company = self.company) if cwip_disabled else cwip_account) gl_entries.append(self.get_gl_dict({ "account": expenses_included_in_valuation, "against": asset_account, "cost_center": d.cost_center, "remarks": self.get("remarks") or _("Accounting Entry for Stock"), "credit": flt(d.landed_cost_voucher_amount), "project": d.project }, item=d)) gl_entries.append(self.get_gl_dict({ "account": asset_account, "against": expenses_included_in_valuation, "cost_center": d.cost_center, "remarks": self.get("remarks") or _("Accounting Entry for Stock"), "debit": flt(d.landed_cost_voucher_amount), "project": d.project }, item=d)) if d.asset: doc = frappe.get_doc("Asset", d.asset) frappe.db.set_value("Asset", d.asset, "gross_purchase_amount", doc.gross_purchase_amount + flt(d.landed_cost_voucher_amount)) frappe.db.set_value("Asset", d.asset, "purchase_receipt_amount", doc.purchase_receipt_amount + flt(d.landed_cost_voucher_amount)) return gl_entries
def get_fixed_asset_account(self): return get_asset_category_account('fixed_asset_account', None, self.name, None, self.asset_category, self.company)