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 check_asset_cwip_enabled(self): # Check if there exists any item with cwip accounting enabled in it's asset category for item in self.get("items"): if item.item_code and item.is_fixed_asset: asset_category = frappe.get_cached_value("Item", item.item_code, "asset_category") if is_cwip_accounting_enabled(asset_category): return 1 return 0
def validate_cwip_accounts(self): for item in self.get('items'): if item.is_fixed_asset and is_cwip_accounting_enabled(item.asset_category): # check cwip accounts before making auto assets # Improves UX by not giving messages of "Assets Created" before throwing error of not finding arbnb account arbnb_account = self.get_company_default("asset_received_but_not_billed") cwip_account = get_asset_account("capital_work_in_progress_account", asset_category = item.asset_category, \ company = self.company) break
def get_asset_gl_entry(self, gl_entries): for item in self.get("items"): if item.is_fixed_asset: if is_cwip_accounting_enabled(item.asset_category): self.add_asset_gl_entries(item, gl_entries) if flt(item.landed_cost_voucher_amount): self.add_lcv_gl_entries(item, gl_entries) # update assets gross amount by its valuation rate # valuation rate is total of net rate, raw mat supp cost, tax amount, lcv amount per item self.update_assets(item, item.valuation_rate) return gl_entries
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 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 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: item.expense_account = warehouse_account[item.warehouse]["account"] else: 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 make_item_gl_entries(self, gl_entries): # item gl entries stock_items = self.get_stock_items() expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation") if self.update_stock and self.auto_accounting_for_stock: warehouse_account = get_warehouse_account_map(self.company) landed_cost_entries = get_item_account_wise_additional_cost(self.name) voucher_wise_stock_value = {} if self.update_stock: for d in frappe.get_all('Stock Ledger Entry', fields = ["voucher_detail_no", "stock_value_difference"], filters={'voucher_no': self.name}): voucher_wise_stock_value.setdefault(d.voucher_detail_no, d.stock_value_difference) valuation_tax_accounts = [d.account_head for d in self.get("taxes") if d.category in ('Valuation', 'Total and Valuation') and flt(d.base_tax_amount_after_discount_amount)] for item in self.get("items"): if flt(item.base_net_amount): account_currency = get_account_currency(item.expense_account) if item.item_code: asset_category = frappe.get_cached_value("Item", item.item_code, "asset_category") if self.update_stock and self.auto_accounting_for_stock and item.item_code in stock_items: # warehouse account warehouse_debit_amount = self.make_stock_adjustment_entry(gl_entries, item, voucher_wise_stock_value, account_currency) gl_entries.append( self.get_gl_dict({ "account": item.expense_account, "against": self.supplier, "debit": warehouse_debit_amount, "remarks": self.get("remarks") or _("Accounting Entry for Stock"), "cost_center": item.cost_center, "project": item.project or self.project }, account_currency, item=item) ) # Amount added through landed-cost-voucher if landed_cost_entries: for account, amount in iteritems(landed_cost_entries[(item.item_code, item.name)]): gl_entries.append(self.get_gl_dict({ "account": account, "against": item.expense_account, "cost_center": item.cost_center, "remarks": self.get("remarks") or _("Accounting Entry for Stock"), "credit": flt(amount), "project": item.project or self.project }, item=item)) # sub-contracting warehouse if flt(item.rm_supp_cost): supplier_warehouse_account = warehouse_account[self.supplier_warehouse]["account"] if not supplier_warehouse_account: frappe.throw(_("Please set account in Warehouse {0}") .format(self.supplier_warehouse)) gl_entries.append(self.get_gl_dict({ "account": supplier_warehouse_account, "against": item.expense_account, "cost_center": item.cost_center, "project": item.project or self.project, "remarks": self.get("remarks") or _("Accounting Entry for Stock"), "credit": flt(item.rm_supp_cost) }, warehouse_account[self.supplier_warehouse]["account_currency"], item=item)) elif not item.is_fixed_asset or (item.is_fixed_asset and not is_cwip_accounting_enabled(asset_category)): expense_account = (item.expense_account if (not item.enable_deferred_expense or self.is_return) else item.deferred_expense_account) if not item.is_fixed_asset: amount = flt(item.base_net_amount, item.precision("base_net_amount")) else: amount = flt(item.base_net_amount + item.item_tax_amount, item.precision("base_net_amount")) gl_entries.append(self.get_gl_dict({ "account": expense_account, "against": self.supplier, "debit": amount, "cost_center": item.cost_center, "project": item.project or self.project }, account_currency, item=item)) # If asset is bought through this document and not linked to PR if self.update_stock and item.landed_cost_voucher_amount: expenses_included_in_asset_valuation = self.get_company_default("expenses_included_in_asset_valuation") # Amount added through landed-cost-voucher gl_entries.append(self.get_gl_dict({ "account": expenses_included_in_asset_valuation, "against": expense_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 or self.project }, item=item)) gl_entries.append(self.get_gl_dict({ "account": expense_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 or self.project }, item=item)) # update gross amount of asset bought through this document assets = frappe.db.get_all('Asset', filters={ 'purchase_invoice': self.name, 'item_code': item.item_code } ) for asset in assets: frappe.db.set_value("Asset", asset.name, "gross_purchase_amount", flt(item.valuation_rate)) frappe.db.set_value("Asset", asset.name, "purchase_receipt_amount", flt(item.valuation_rate)) if self.auto_accounting_for_stock and self.is_opening == "No" and \ item.item_code in stock_items and item.item_tax_amount: # Post reverse entry for Stock-Received-But-Not-Billed if it is booked in Purchase Receipt if item.purchase_receipt and valuation_tax_accounts: negative_expense_booked_in_pr = frappe.db.sql("""select name from `tabGL Entry` where voucher_type='Purchase Receipt' and voucher_no=%s and account in %s""", (item.purchase_receipt, valuation_tax_accounts)) if not negative_expense_booked_in_pr: gl_entries.append( self.get_gl_dict({ "account": self.stock_received_but_not_billed, "against": self.supplier, "debit": flt(item.item_tax_amount, item.precision("item_tax_amount")), "remarks": self.remarks or "Accounting Entry for Stock", "cost_center": self.cost_center, "project": item.project or self.project }, item=item) ) self.negative_expense_to_be_booked += flt(item.item_tax_amount, \ item.precision("item_tax_amount"))