Пример #1
0
	def get_gl_entries(self, warehouse_account=None, default_expense_account=None,
			default_cost_center=None):

		if not warehouse_account:
			warehouse_account = get_warehouse_account_map()

		sle_map = self.get_stock_ledger_details()
		voucher_details = self.get_voucher_details(default_expense_account, default_cost_center, sle_map)

		gl_list = []
		warehouse_with_no_account = []

		for item_row in voucher_details:
			sle_list = sle_map.get(item_row.name)
			if sle_list:
				for sle in sle_list:
					if warehouse_account.get(sle.warehouse):
						# from warehouse account

						self.check_expense_account(item_row)

						# If the item does not have the allow zero valuation rate flag set
						# and ( valuation rate not mentioned in an incoming entry
						# or incoming entry not found while delivering the item),
						# try to pick valuation rate from previous sle or Item master and update in SLE
						# Otherwise, throw an exception

						if not sle.stock_value_difference and self.doctype != "Stock Reconciliation" \
							and not item_row.get("allow_zero_valuation_rate"):

							sle = self.update_stock_ledger_entries(sle)

						gl_list.append(self.get_gl_dict({
							"account": warehouse_account[sle.warehouse]["account"],
							"against": item_row.expense_account,
							"cost_center": item_row.cost_center,
							"remarks": self.get("remarks") or "Accounting Entry for Stock",
							"debit": flt(sle.stock_value_difference, 2),
						}, warehouse_account[sle.warehouse]["account_currency"]))

						# to target warehouse / expense account
						gl_list.append(self.get_gl_dict({
							"account": item_row.expense_account,
							"against": warehouse_account[sle.warehouse]["account"],
							"cost_center": item_row.cost_center,
							"remarks": self.get("remarks") or "Accounting Entry for Stock",
							"credit": flt(sle.stock_value_difference, 2),
							"project": item_row.get("project") or self.get("project")
						}))
					elif sle.warehouse not in warehouse_with_no_account:
						warehouse_with_no_account.append(sle.warehouse)

		if warehouse_with_no_account:
			for wh in warehouse_with_no_account:
				if frappe.db.get_value("Warehouse", wh, "company"):
					frappe.throw(_("Warehouse {0} is not linked to any account, please mention the account in  the warehouse record or set default inventory account in company {1}.").format(wh, self.company))

		return process_gl_map(gl_list)
Пример #2
0
    def get_gl_entries(self, warehouse_account=None, default_expense_account=None, default_cost_center=None):

        if not warehouse_account:
            warehouse_account = get_warehouse_account()

        sle_map = self.get_stock_ledger_details()
        voucher_details = self.get_voucher_details(default_expense_account, default_cost_center, sle_map)

        gl_list = []
        warehouse_with_no_account = []

        for detail in voucher_details:
            sle_list = sle_map.get(detail.name)
            if sle_list:
                for sle in sle_list:
                    if warehouse_account.get(sle.warehouse):
                        # from warehouse account

                        self.check_expense_account(detail)

                        gl_list.append(
                            self.get_gl_dict(
                                {
                                    "account": warehouse_account[sle.warehouse]["name"],
                                    "against": detail.expense_account,
                                    "cost_center": detail.cost_center,
                                    "remarks": self.get("remarks") or "Accounting Entry for Stock",
                                    "debit": flt(sle.stock_value_difference, 2),
                                },
                                warehouse_account[sle.warehouse]["account_currency"],
                            )
                        )

                        # to target warehouse / expense account
                        gl_list.append(
                            self.get_gl_dict(
                                {
                                    "account": detail.expense_account,
                                    "against": warehouse_account[sle.warehouse]["name"],
                                    "cost_center": detail.cost_center,
                                    "remarks": self.get("remarks") or "Accounting Entry for Stock",
                                    "credit": flt(sle.stock_value_difference, 2),
                                    "project": detail.get("project") or self.get("project"),
                                }
                            )
                        )
                    elif sle.warehouse not in warehouse_with_no_account:
                        warehouse_with_no_account.append(sle.warehouse)

        if warehouse_with_no_account:
            msgprint(
                _("No accounting entries for the following warehouses") + ": \n" + "\n".join(warehouse_with_no_account)
            )

        return process_gl_map(gl_list)
Пример #3
0
	def get_gl_entries(self, warehouse_account=None, default_expense_account=None,
			default_cost_center=None):

		if not warehouse_account:
			warehouse_account = get_warehouse_account()

		sle_map = self.get_stock_ledger_details()
		voucher_details = self.get_voucher_details(default_expense_account, default_cost_center, sle_map)

		gl_list = []
		warehouse_with_no_account = []
		
		for item_row in voucher_details:
			sle_list = sle_map.get(item_row.name)
			if sle_list:
				for sle in sle_list:
					if warehouse_account.get(sle.warehouse):
						# from warehouse account
						
						self.check_expense_account(item_row)

						if not sle.stock_value_difference:
							self.update_stock_ledger_entries(sle)
							self.validate_negative_stock(sle)

						gl_list.append(self.get_gl_dict({
							"account": warehouse_account[sle.warehouse]["name"],
							"against": item_row.expense_account,
							"cost_center": item_row.cost_center,
							"remarks": self.get("remarks") or "Accounting Entry for Stock",
							"debit": flt(sle.stock_value_difference, 2),
						}, warehouse_account[sle.warehouse]["account_currency"]))

						# to target warehouse / expense account
						gl_list.append(self.get_gl_dict({
							"account": item_row.expense_account,
							"against": warehouse_account[sle.warehouse]["name"],
							"cost_center": item_row.cost_center,
							"remarks": self.get("remarks") or "Accounting Entry for Stock",
							"credit": flt(sle.stock_value_difference, 2),
							"project": item_row.get("project") or self.get("project")
						}))
					elif sle.warehouse not in warehouse_with_no_account:
						warehouse_with_no_account.append(sle.warehouse)

		if warehouse_with_no_account:
			for wh in warehouse_with_no_account:
				if frappe.db.get_value("Warehouse", wh, "company"):
					frappe.throw(_("Warehouse {0} is not linked to any account, please create/link the corresponding (Asset) account for the warehouse.").format(wh))
					
			msgprint(_("No accounting entries for the following warehouses") + ": \n" +
				"\n".join(warehouse_with_no_account))

		return process_gl_map(gl_list)
Пример #4
0
	def get_gl_entries(self, warehouse_account=None, default_expense_account=None,
			default_cost_center=None, allow_negative_stock=False):

		# block_negative_stock(allow_negative_stock)

		if not warehouse_account:
			warehouse_account = get_warehouse_account()

		sle_map = self.get_stock_ledger_details()
		voucher_details = self.get_voucher_details(default_expense_account, default_cost_center, sle_map)

		gl_list = []
		warehouse_with_no_account = []
		for detail in voucher_details:
			sle_list = sle_map.get(detail.name)
			if sle_list:
				for sle in sle_list:
					if warehouse_account.get(sle.warehouse):
						# from warehouse account

						self.check_expense_account(detail)

						stock_value_difference = flt(sle.stock_value_difference, 2)
						if not stock_value_difference:
							valuation_rate = get_valuation_rate(sle.item_code, sle.warehouse)
							stock_value_difference = flt(sle.actual_qty)*flt(valuation_rate)

						gl_list.append(self.get_gl_dict({
							"account": warehouse_account[sle.warehouse],
							"against": detail.expense_account,
							"cost_center": detail.cost_center,
							"remarks": self.get("remarks") or "Accounting Entry for Stock",
							"debit": stock_value_difference
						}))

						# to target warehouse / expense account
						gl_list.append(self.get_gl_dict({
							"account": detail.expense_account,
							"against": warehouse_account[sle.warehouse],
							"cost_center": detail.cost_center,
							"remarks": self.get("remarks") or "Accounting Entry for Stock",
							"credit": stock_value_difference
						}))
					elif sle.warehouse not in warehouse_with_no_account:
						warehouse_with_no_account.append(sle.warehouse)

		if warehouse_with_no_account:
			msgprint(_("No accounting entries for the following warehouses") + ": \n" +
				"\n".join(warehouse_with_no_account))

		return process_gl_map(gl_list)
	def get_gl_entries(self, warehouse_account=None):
		from erpnext.accounts.general_ledger import process_gl_map

		stock_rbnb = self.get_company_default("stock_received_but_not_billed")
		expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")

		gl_entries = []
		warehouse_with_no_account = []
		negative_expense_to_be_booked = 0.0
		stock_items = self.get_stock_items()
		for d in self.get("purchase_receipt_details"):
			if d.item_code in stock_items and flt(d.valuation_rate) and flt(d.qty):
				if warehouse_account.get(d.warehouse):

					# warehouse account
					gl_entries.append(self.get_gl_dict({
						"account": warehouse_account[d.warehouse],
						"against": stock_rbnb,
						"cost_center": d.cost_center,
						"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
						"debit": flt(flt(d.valuation_rate) * flt(d.qty) * flt(d.conversion_factor),
							self.precision("valuation_rate", d))
					}))

					# stock received but not billed
					gl_entries.append(self.get_gl_dict({
						"account": stock_rbnb,
						"against": warehouse_account[d.warehouse],
						"cost_center": d.cost_center,
						"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
						"credit": flt(d.base_amount, self.precision("base_amount", d))
					}))

					negative_expense_to_be_booked += flt(d.item_tax_amount)

					# Amount added through landed-cost-voucher
					if flt(d.landed_cost_voucher_amount):
						gl_entries.append(self.get_gl_dict({
							"account": expenses_included_in_valuation,
							"against": warehouse_account[d.warehouse],
							"cost_center": d.cost_center,
							"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
							"credit": flt(d.landed_cost_voucher_amount)
						}))

					# sub-contracting warehouse
					if flt(d.rm_supp_cost) and warehouse_account.get(self.supplier_warehouse):
						gl_entries.append(self.get_gl_dict({
							"account": warehouse_account[self.supplier_warehouse],
							"against": warehouse_account[d.warehouse],
							"cost_center": d.cost_center,
							"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
							"credit": flt(d.rm_supp_cost)
						}))

				elif d.warehouse not in warehouse_with_no_account or \
					d.rejected_warehouse not in warehouse_with_no_account:
						warehouse_with_no_account.append(d.warehouse)

		# Cost center-wise amount breakup for other charges included for valuation
		valuation_tax = {}
		for tax in self.get("other_charges"):
			if tax.category in ("Valuation", "Valuation and Total") and flt(tax.tax_amount):
				if not tax.cost_center:
					frappe.throw(_("Cost Center is required in row {0} in Taxes table for type {1}").format(tax.idx, _(tax.category)))
				valuation_tax.setdefault(tax.cost_center, 0)
				valuation_tax[tax.cost_center] += \
					(tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.tax_amount)

		if negative_expense_to_be_booked and valuation_tax:
			# Backward compatibility:
			# If expenses_included_in_valuation account has been credited in against PI
			# and charges added via Landed Cost Voucher,
			# post valuation related charges on "Stock Received But Not Billed"

			negative_expense_booked_in_pi = frappe.db.sql("""select name from `tabPurchase Invoice Item` pi
				where docstatus = 1 and purchase_receipt=%s
				and exists(select name from `tabGL Entry` where voucher_type='Purchase Invoice'
					and voucher_no=pi.parent and account=%s)""", (self.name, expenses_included_in_valuation))

			if negative_expense_booked_in_pi:
				expenses_included_in_valuation = stock_rbnb

			against_account = ", ".join([d.account for d in gl_entries if flt(d.debit) > 0])
			total_valuation_amount = sum(valuation_tax.values())
			amount_including_divisional_loss = negative_expense_to_be_booked
			i = 1
			for cost_center, amount in valuation_tax.items():
				if i == len(valuation_tax):
					applicable_amount = amount_including_divisional_loss
				else:
					applicable_amount = negative_expense_to_be_booked * (amount / total_valuation_amount)
					amount_including_divisional_loss -= applicable_amount

				gl_entries.append(
					self.get_gl_dict({
						"account": expenses_included_in_valuation,
						"cost_center": cost_center,
						"credit": applicable_amount,
						"remarks": self.remarks or _("Accounting Entry for Stock"),
						"against": against_account
					})
				)

				i += 1

		if warehouse_with_no_account:
			frappe.msgprint(_("No accounting entries for the following warehouses") + ": \n" +
				"\n".join(warehouse_with_no_account))

		return process_gl_map(gl_entries)
Пример #6
0
    def get_gl_entries(self, warehouse_account=None):
        from erpnext.accounts.general_ledger import process_gl_map

        stock_rbnb = self.get_company_default("stock_received_but_not_billed")
        landed_cost_entries = get_item_account_wise_additional_cost(self.name)
        expenses_included_in_valuation = self.get_company_default(
            "expenses_included_in_valuation")

        gl_entries = []
        warehouse_with_no_account = []
        negative_expense_to_be_booked = 0.0
        stock_items = self.get_stock_items()
        for d in self.get("items"):
            if d.item_code in stock_items and flt(d.valuation_rate) and flt(
                    d.qty):
                if warehouse_account.get(d.warehouse):
                    stock_value_diff = frappe.db.get_value(
                        "Stock Ledger Entry", {
                            "voucher_type": "Purchase Receipt",
                            "voucher_no": self.name,
                            "voucher_detail_no": d.name,
                            "warehouse": d.warehouse
                        }, "stock_value_difference")

                    if not stock_value_diff:
                        continue
                    gl_entries.append(
                        self.get_gl_dict(
                            {
                                "account":
                                warehouse_account[d.warehouse]["account"],
                                "against":
                                stock_rbnb,
                                "cost_center":
                                d.cost_center,
                                "remarks":
                                self.get("remarks")
                                or _("Accounting Entry for Stock"),
                                "debit":
                                stock_value_diff
                            },
                            warehouse_account[d.warehouse]["account_currency"],
                            item=d))

                    # stock received but not billed
                    stock_rbnb_currency = get_account_currency(stock_rbnb)
                    gl_entries.append(self.get_gl_dict({
                     "account": stock_rbnb,
                     "against": warehouse_account[d.warehouse]["account"],
                     "cost_center": d.cost_center,
                     "remarks": self.get("remarks") or _("Accounting Entry for Stock"),
                     "credit": flt(d.base_net_amount, d.precision("base_net_amount")),
                     "credit_in_account_currency": flt(d.base_net_amount, d.precision("base_net_amount")) \
                      if stock_rbnb_currency==self.company_currency else flt(d.net_amount, d.precision("net_amount"))
                    }, stock_rbnb_currency, item=d))

                    negative_expense_to_be_booked += flt(d.item_tax_amount)

                    # Amount added through landed-cost-voucher
                    if d.landed_cost_voucher_amount and landed_cost_entries:
                        for account, amount in iteritems(
                                landed_cost_entries[(d.item_code, d.name)]):
                            gl_entries.append(
                                self.get_gl_dict(
                                    {
                                        "account":
                                        account,
                                        "against":
                                        warehouse_account[
                                            d.warehouse]["account"],
                                        "cost_center":
                                        d.cost_center,
                                        "remarks":
                                        self.get("remarks")
                                        or _("Accounting Entry for Stock"),
                                        "credit":
                                        flt(amount),
                                        "project":
                                        d.project
                                    },
                                    item=d))

                    # sub-contracting warehouse
                    if flt(d.rm_supp_cost) and warehouse_account.get(
                            self.supplier_warehouse):
                        gl_entries.append(
                            self.get_gl_dict(
                                {
                                    "account":
                                    warehouse_account[
                                        self.supplier_warehouse]["account"],
                                    "against":
                                    warehouse_account[d.warehouse]["account"],
                                    "cost_center":
                                    d.cost_center,
                                    "remarks":
                                    self.get("remarks")
                                    or _("Accounting Entry for Stock"),
                                    "credit":
                                    flt(d.rm_supp_cost)
                                },
                                warehouse_account[self.supplier_warehouse]
                                ["account_currency"],
                                item=d))

                    # divisional loss adjustment
                    valuation_amount_as_per_doc = flt(d.base_net_amount, d.precision("base_net_amount")) + \
                     flt(d.landed_cost_voucher_amount) + flt(d.rm_supp_cost) + flt(d.item_tax_amount)

                    divisional_loss = flt(
                        valuation_amount_as_per_doc - stock_value_diff,
                        d.precision("base_net_amount"))

                    if divisional_loss:
                        if self.is_return or flt(d.item_tax_amount):
                            loss_account = expenses_included_in_valuation
                        else:
                            loss_account = stock_rbnb

                        gl_entries.append(
                            self.get_gl_dict(
                                {
                                    "account":
                                    loss_account,
                                    "against":
                                    warehouse_account[d.warehouse]["account"],
                                    "cost_center":
                                    d.cost_center,
                                    "remarks":
                                    self.get("remarks")
                                    or _("Accounting Entry for Stock"),
                                    "debit":
                                    divisional_loss,
                                    "project":
                                    d.project
                                },
                                stock_rbnb_currency,
                                item=d))

                elif d.warehouse not in warehouse_with_no_account or \
                 d.rejected_warehouse not in warehouse_with_no_account:
                    warehouse_with_no_account.append(d.warehouse)

        self.get_asset_gl_entry(gl_entries)
        # Cost center-wise amount breakup for other charges included for valuation
        valuation_tax = {}
        for tax in self.get("taxes"):
            if tax.category in ("Valuation", "Valuation and Total") and flt(
                    tax.base_tax_amount_after_discount_amount):
                if not tax.cost_center:
                    frappe.throw(
                        _("Cost Center is required in row {0} in Taxes table for type {1}"
                          ).format(tax.idx, _(tax.category)))
                valuation_tax.setdefault(tax.name, 0)
                valuation_tax[tax.name] += \
                 (tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.base_tax_amount_after_discount_amount)

        if negative_expense_to_be_booked and valuation_tax:
            # Backward compatibility:
            # If expenses_included_in_valuation account has been credited in against PI
            # and charges added via Landed Cost Voucher,
            # post valuation related charges on "Stock Received But Not Billed"
            # introduced in 2014 for backward compatibility of expenses already booked in expenses_included_in_valuation account

            negative_expense_booked_in_pi = frappe.db.sql(
                """select name from `tabPurchase Invoice Item` pi
				where docstatus = 1 and purchase_receipt=%s
				and exists(select name from `tabGL Entry` where voucher_type='Purchase Invoice'
					and voucher_no=pi.parent and account=%s)""",
                (self.name, expenses_included_in_valuation))

            against_account = ", ".join(
                [d.account for d in gl_entries if flt(d.debit) > 0])
            total_valuation_amount = sum(valuation_tax.values())
            amount_including_divisional_loss = negative_expense_to_be_booked
            i = 1
            for tax in self.get("taxes"):
                if valuation_tax.get(tax.name):

                    if negative_expense_booked_in_pi:
                        account = stock_rbnb
                    else:
                        account = tax.account_head

                    if i == len(valuation_tax):
                        applicable_amount = amount_including_divisional_loss
                    else:
                        applicable_amount = negative_expense_to_be_booked * (
                            valuation_tax[tax.name] / total_valuation_amount)
                        amount_including_divisional_loss -= applicable_amount

                    gl_entries.append(
                        self.get_gl_dict(
                            {
                                "account":
                                account,
                                "cost_center":
                                tax.cost_center,
                                "credit":
                                applicable_amount,
                                "remarks":
                                self.remarks
                                or _("Accounting Entry for Stock"),
                                "against":
                                against_account
                            },
                            item=tax))

                    i += 1

        if warehouse_with_no_account:
            frappe.msgprint(
                _("No accounting entries for the following warehouses") +
                ": \n" + "\n".join(warehouse_with_no_account))

        return process_gl_map(gl_entries)
Пример #7
0
    def get_gl_entries(self,
                       warehouse_account=None,
                       default_expense_account=None,
                       default_cost_center=None):

        if not warehouse_account:
            warehouse_account = get_warehouse_account_map(self.company)

        sle_map = self.get_stock_ledger_details()
        voucher_details = self.get_voucher_details(default_expense_account,
                                                   default_cost_center,
                                                   sle_map)

        gl_list = []
        warehouse_with_no_account = []

        for item_row in voucher_details:
            sle_list = sle_map.get(item_row.name)
            if sle_list:
                for sle in sle_list:
                    if warehouse_account.get(sle.warehouse):
                        # from warehouse account

                        self.check_expense_account(item_row)

                        # If the item does not have the allow zero valuation rate flag set
                        # and ( valuation rate not mentioned in an incoming entry
                        # or incoming entry not found while delivering the item),
                        # try to pick valuation rate from previous sle or Item master and update in SLE
                        # Otherwise, throw an exception

                        if not sle.stock_value_difference and self.doctype != "Stock Reconciliation" \
                         and not item_row.get("allow_zero_valuation_rate"):

                            sle = self.update_stock_ledger_entries(sle)

                        gl_list.append(
                            self.get_gl_dict(
                                {
                                    "account":
                                    warehouse_account[
                                        sle.warehouse]["account"],
                                    "against":
                                    item_row.expense_account,
                                    "cost_center":
                                    item_row.cost_center,
                                    "remarks":
                                    self.get("remarks")
                                    or "Accounting Entry for Stock",
                                    "debit":
                                    flt(sle.stock_value_difference, 2),
                                }, warehouse_account[sle.warehouse]
                                ["account_currency"]))

                        # to target warehouse / expense account
                        gl_list.append(
                            self.get_gl_dict({
                                "account":
                                item_row.expense_account,
                                "against":
                                warehouse_account[sle.warehouse]["account"],
                                "cost_center":
                                item_row.cost_center,
                                "remarks":
                                self.get("remarks")
                                or "Accounting Entry for Stock",
                                "credit":
                                flt(sle.stock_value_difference, 2),
                                "project":
                                item_row.get("project") or self.get("project")
                            }))
                    elif sle.warehouse not in warehouse_with_no_account:
                        warehouse_with_no_account.append(sle.warehouse)

        if warehouse_with_no_account:
            for wh in warehouse_with_no_account:
                if frappe.db.get_value("Warehouse", wh, "company"):
                    frappe.throw(
                        _("Warehouse {0} is not linked to any account, please mention the account in  the warehouse record or set default inventory account in company {1}."
                          ).format(wh, self.company))

        return process_gl_map(gl_list)
Пример #8
0
    def get_gl_entries(self,
                       warehouse_account=None,
                       default_expense_account=None,
                       default_cost_center=None):

        if not warehouse_account:
            warehouse_account = get_warehouse_account()

        sle_map = self.get_stock_ledger_details()
        voucher_details = self.get_voucher_details(default_expense_account,
                                                   default_cost_center,
                                                   sle_map)

        gl_list = []
        warehouse_with_no_account = []
        for detail in voucher_details:
            sle_list = sle_map.get(detail.name)
            if sle_list:
                for sle in sle_list:
                    if warehouse_account.get(sle.warehouse):
                        # from warehouse account

                        self.check_expense_account(detail)

                        gl_list.append(
                            self.get_gl_dict({
                                "account":
                                warehouse_account[sle.warehouse],
                                "against":
                                detail.expense_account,
                                "cost_center":
                                detail.cost_center,
                                "remarks":
                                self.get("remarks")
                                or "Accounting Entry for Stock",
                                "debit":
                                flt(sle.stock_value_difference, 2)
                            }))

                        # to target warehouse / expense account
                        gl_list.append(
                            self.get_gl_dict({
                                "account":
                                detail.expense_account,
                                "against":
                                warehouse_account[sle.warehouse],
                                "cost_center":
                                detail.cost_center,
                                "remarks":
                                self.get("remarks")
                                or "Accounting Entry for Stock",
                                "credit":
                                flt(sle.stock_value_difference, 2)
                            }))
                    elif sle.warehouse not in warehouse_with_no_account:
                        warehouse_with_no_account.append(sle.warehouse)

        if warehouse_with_no_account:
            msgprint(
                _("No accounting entries for the following warehouses") +
                ": \n" + "\n".join(warehouse_with_no_account))

        return process_gl_map(gl_list)
Пример #9
0
    def get_gl_entries(self, warehouse_account=None):
        from erpnext.accounts.general_ledger import process_gl_map

        stock_rbnb = self.get_company_default("stock_received_but_not_billed")
        expenses_included_in_valuation = self.get_company_default(
            "expenses_included_in_valuation")

        gl_entries = []
        warehouse_with_no_account = []
        negative_expense_to_be_booked = 0.0
        stock_items = self.get_stock_items()
        for d in self.get("items"):
            if d.item_code in stock_items and flt(d.valuation_rate) and flt(
                    d.qty):
                if warehouse_account.get(d.warehouse):

                    # warehouse account
                    gl_entries.append(
                        self.get_gl_dict({
                            "account":
                            warehouse_account[d.warehouse],
                            "against":
                            stock_rbnb,
                            "cost_center":
                            d.cost_center,
                            "remarks":
                            self.get("remarks")
                            or _("Accounting Entry for Stock"),
                            "debit":
                            flt(
                                flt(d.valuation_rate) * flt(d.qty) *
                                flt(d.conversion_factor),
                                self.precision("valuation_rate", d))
                        }))

                    # stock received but not billed
                    gl_entries.append(
                        self.get_gl_dict({
                            "account":
                            stock_rbnb,
                            "against":
                            warehouse_account[d.warehouse],
                            "cost_center":
                            d.cost_center,
                            "remarks":
                            self.get("remarks")
                            or _("Accounting Entry for Stock"),
                            "credit":
                            flt(d.base_amount,
                                self.precision("base_amount", d))
                        }))

                    negative_expense_to_be_booked += flt(d.item_tax_amount)

                    # Amount added through landed-cost-voucher
                    if flt(d.landed_cost_voucher_amount):
                        gl_entries.append(
                            self.get_gl_dict({
                                "account":
                                expenses_included_in_valuation,
                                "against":
                                warehouse_account[d.warehouse],
                                "cost_center":
                                d.cost_center,
                                "remarks":
                                self.get("remarks")
                                or _("Accounting Entry for Stock"),
                                "credit":
                                flt(d.landed_cost_voucher_amount)
                            }))

                    # sub-contracting warehouse
                    if flt(d.rm_supp_cost) and warehouse_account.get(
                            self.supplier_warehouse):
                        gl_entries.append(
                            self.get_gl_dict({
                                "account":
                                warehouse_account[self.supplier_warehouse],
                                "against":
                                warehouse_account[d.warehouse],
                                "cost_center":
                                d.cost_center,
                                "remarks":
                                self.get("remarks")
                                or _("Accounting Entry for Stock"),
                                "credit":
                                flt(d.rm_supp_cost)
                            }))

                elif d.warehouse not in warehouse_with_no_account or \
                 d.rejected_warehouse not in warehouse_with_no_account:
                    warehouse_with_no_account.append(d.warehouse)

        # Cost center-wise amount breakup for other charges included for valuation
        valuation_tax = {}
        for tax in self.get("taxes"):
            if tax.category in ("Valuation", "Valuation and Total") and flt(
                    tax.tax_amount):
                if not tax.cost_center:
                    frappe.throw(
                        _("Cost Center is required in row {0} in Taxes table for type {1}"
                          ).format(tax.idx, _(tax.category)))
                valuation_tax.setdefault(tax.cost_center, 0)
                valuation_tax[tax.cost_center] += \
                 (tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.tax_amount)

        if negative_expense_to_be_booked and valuation_tax:
            # Backward compatibility:
            # If expenses_included_in_valuation account has been credited in against PI
            # and charges added via Landed Cost Voucher,
            # post valuation related charges on "Stock Received But Not Billed"

            negative_expense_booked_in_pi = frappe.db.sql(
                """select name from `tabPurchase Invoice Item` pi
				where docstatus = 1 and purchase_receipt=%s
				and exists(select name from `tabGL Entry` where voucher_type='Purchase Invoice'
					and voucher_no=pi.parent and account=%s)""",
                (self.name, expenses_included_in_valuation))

            if negative_expense_booked_in_pi:
                expenses_included_in_valuation = stock_rbnb

            against_account = ", ".join(
                [d.account for d in gl_entries if flt(d.debit) > 0])
            total_valuation_amount = sum(valuation_tax.values())
            amount_including_divisional_loss = negative_expense_to_be_booked
            i = 1
            for cost_center, amount in valuation_tax.items():
                if i == len(valuation_tax):
                    applicable_amount = amount_including_divisional_loss
                else:
                    applicable_amount = negative_expense_to_be_booked * (
                        amount / total_valuation_amount)
                    amount_including_divisional_loss -= applicable_amount

                gl_entries.append(
                    self.get_gl_dict({
                        "account":
                        expenses_included_in_valuation,
                        "cost_center":
                        cost_center,
                        "credit":
                        applicable_amount,
                        "remarks":
                        self.remarks or _("Accounting Entry for Stock"),
                        "against":
                        against_account
                    }))

                i += 1

        if warehouse_with_no_account:
            frappe.msgprint(
                _("No accounting entries for the following warehouses") +
                ": \n" + "\n".join(warehouse_with_no_account))

        return process_gl_map(gl_entries)
Пример #10
0
    def get_gl_entries(self,
                       warehouse_account=None,
                       default_expense_account=None,
                       default_cost_center=None):

        if not warehouse_account:
            warehouse_account = get_warehouse_account()

        sle_map = self.get_stock_ledger_details()
        voucher_details = self.get_voucher_details(default_expense_account,
                                                   default_cost_center,
                                                   sle_map)

        gl_list = []
        warehouse_with_no_account = []

        for item_row in voucher_details:
            sle_list = sle_map.get(item_row.name)
            if sle_list:
                for sle in sle_list:
                    if warehouse_account.get(sle.warehouse):
                        # from warehouse account

                        self.check_expense_account(item_row)

                        if not sle.stock_value_difference:
                            self.update_stock_ledger_entries(sle)
                            self.validate_negative_stock(sle)

                        gl_list.append(
                            self.get_gl_dict(
                                {
                                    "account":
                                    warehouse_account[sle.warehouse]["name"],
                                    "against":
                                    item_row.expense_account,
                                    "cost_center":
                                    item_row.cost_center,
                                    "remarks":
                                    self.get("remarks")
                                    or "Accounting Entry for Stock",
                                    "debit":
                                    flt(sle.stock_value_difference, 2),
                                }, warehouse_account[sle.warehouse]
                                ["account_currency"]))

                        # to target warehouse / expense account
                        gl_list.append(
                            self.get_gl_dict({
                                "account":
                                item_row.expense_account,
                                "against":
                                warehouse_account[sle.warehouse]["name"],
                                "cost_center":
                                item_row.cost_center,
                                "remarks":
                                self.get("remarks")
                                or "Accounting Entry for Stock",
                                "credit":
                                flt(sle.stock_value_difference, 2),
                                "project":
                                item_row.get("project") or self.get("project")
                            }))
                    elif sle.warehouse not in warehouse_with_no_account:
                        warehouse_with_no_account.append(sle.warehouse)

        if warehouse_with_no_account:
            for wh in warehouse_with_no_account:
                if frappe.db.get_value("Warehouse", wh, "company"):
                    frappe.throw(
                        _("Warehouse {0} is not linked to any account, please create/link the corresponding (Asset) account for the warehouse."
                          ).format(wh))

            msgprint(
                _("No accounting entries for the following warehouses") +
                ": \n" + "\n".join(warehouse_with_no_account))

        return process_gl_map(gl_list)
Пример #11
0
	def get_gl_entries(self, warehouse_account=None, default_expense_account=None,
			default_cost_center=None):

		if not warehouse_account:
			warehouse_account = get_warehouse_account()

		sle_map = self.get_stock_ledger_details()
		voucher_details = self.get_voucher_details(default_expense_account, default_cost_center, sle_map)

		gl_list = []
		warehouse_with_no_account = []

		for item_row in voucher_details:
			sle_list = sle_map.get(item_row.name)
			if sle_list:
				for sle in sle_list:
					if warehouse_account.get(sle.warehouse):
						# from warehouse account
						
						self.check_expense_account(item_row)

						# If item is not a sample item 
						# and ( valuation rate not mentioned in an incoming entry
						# or incoming entry not found while delivering the item), 
						# try to pick valuation rate from previous sle or Item master and update in SLE
						# Otherwise, throw an exception

						if not sle.stock_value_difference and self.doctype != "Stock Reconciliation" \
							and not item_row.get("is_sample_item"):

							sle = self.update_stock_ledger_entries(sle)

						gl_list.append(self.get_gl_dict({
							"account": warehouse_account[sle.warehouse]["name"],
							"against": item_row.expense_account,
							"cost_center": item_row.cost_center,
							"remarks": self.get("remarks") or "Accounting Entry for Stock",
							"debit": flt(sle.stock_value_difference, 2),
						}, warehouse_account[sle.warehouse]["account_currency"]))

						# to target warehouse / expense account
						gl_list.append(self.get_gl_dict({
							"account": item_row.expense_account,
							"against": warehouse_account[sle.warehouse]["name"],
							"cost_center": item_row.cost_center,
							"remarks": self.get("remarks") or "Accounting Entry for Stock",
							"credit": flt(sle.stock_value_difference, 2),
							"project": item_row.get("project") or self.get("project")
						}))
					elif sle.warehouse not in warehouse_with_no_account:
						warehouse_with_no_account.append(sle.warehouse)

		if warehouse_with_no_account:
			for wh in warehouse_with_no_account:
				if frappe.db.get_value("Warehouse", wh, "company"):
					frappe.throw(_("Warehouse {0} is not linked to any account, please create/link the corresponding (Asset) account for the warehouse.").format(wh))
					
			msgprint(_("No accounting entries for the following warehouses") + ": \n" +
				"\n".join(warehouse_with_no_account))

		return process_gl_map(gl_list)
Пример #12
0
    def get_gl_entries(self,
                       warehouse_account=None,
                       default_expense_account=None,
                       default_cost_center=None):

        if not warehouse_account:
            warehouse_account = get_warehouse_account_map(self.company)

        sle_map = self.get_stock_ledger_details()
        voucher_details = self.get_voucher_details(default_expense_account,
                                                   default_cost_center,
                                                   sle_map)

        gl_list = []
        warehouse_with_no_account = []
        precision = self.get_debit_field_precision()
        for item_row in voucher_details:

            sle_list = sle_map.get(item_row.name)
            if sle_list:
                for sle in sle_list:
                    if warehouse_account.get(sle.warehouse):
                        # from warehouse account

                        self.check_expense_account(item_row)

                        # expense account/ target_warehouse / source_warehouse
                        if item_row.get("target_warehouse"):
                            warehouse = item_row.get("target_warehouse")
                            expense_account = warehouse_account[warehouse][
                                "account"]
                        else:
                            expense_account = item_row.expense_account

                        gl_list.append(
                            self.get_gl_dict(
                                {
                                    "account":
                                    warehouse_account[
                                        sle.warehouse]["account"],
                                    "against":
                                    expense_account,
                                    "cost_center":
                                    item_row.cost_center,
                                    "project":
                                    item_row.project or self.get("project"),
                                    "remarks":
                                    self.get("remarks")
                                    or _("Accounting Entry for Stock"),
                                    "debit":
                                    flt(sle.stock_value_difference, precision),
                                    "is_opening":
                                    item_row.get("is_opening")
                                    or self.get("is_opening") or "No",
                                },
                                warehouse_account[sle.warehouse]
                                ["account_currency"],
                                item=item_row,
                            ))

                        gl_list.append(
                            self.get_gl_dict(
                                {
                                    "account":
                                    expense_account,
                                    "against":
                                    warehouse_account[
                                        sle.warehouse]["account"],
                                    "cost_center":
                                    item_row.cost_center,
                                    "remarks":
                                    self.get("remarks")
                                    or _("Accounting Entry for Stock"),
                                    "credit":
                                    flt(sle.stock_value_difference, precision),
                                    "project":
                                    item_row.get("project")
                                    or self.get("project"),
                                    "is_opening":
                                    item_row.get("is_opening")
                                    or self.get("is_opening") or "No",
                                },
                                item=item_row,
                            ))
                    elif sle.warehouse not in warehouse_with_no_account:
                        warehouse_with_no_account.append(sle.warehouse)

        if warehouse_with_no_account:
            for wh in warehouse_with_no_account:
                if frappe.db.get_value("Warehouse", wh, "company"):
                    frappe.throw(
                        _("Warehouse {0} is not linked to any account, please mention the account in the warehouse record or set default inventory account in company {1}."
                          ).format(wh, self.company))

        return process_gl_map(gl_list, precision=precision)
Пример #13
0
def validate_with_delivery_note(self):
    # We are only doing this:
    # Make SLEs for changed qtys
    # Make the GL wrt abv
    # make_sl_entries & make_gl_entries handles cancellation

    # not stable
    return
    if self.update_stock == 1:
        # do nothing if updating stock
        return
    sl_entries = []
    changed_rows = []
    # everything wrt stock_qty
    for d in [
            x for x in self.items
            if x.validate_with_delivery_note and x.warehouse
    ]:
        if frappe.db.get_value("Item", d.item_code,
                               "is_stock_item") == 1 and flt(d.stock_qty):
            delivered_qty = 0
            if d.dn_detail:
                delivered_qty = frappe.get_value("Delivery Note Item",
                                                 d.dn_detail, "stock_qty")
            qty_change = d.stock_qty - delivered_qty
            # qty_change
            # -ve	: got return
            # +ve	: gave more
            # 0		: continue
            if qty_change == 0:
                continue

            # return rate- code copied from selling_controller.py
            return_rate = 0
            if cint(self.is_return
                    ) and self.return_against and self.docstatus == 1:
                return_rate = self.get_incoming_rate_for_sales_return(
                    d.item_code, self.return_against)

            sl_entries.append(
                self.get_sl_entries(
                    d, {
                        "actual_qty": -1 * flt(qty_change),
                        "incoming_rate": return_rate,
                        "parent": "consoleerp-{}".format(self.name)
                    }))
            changed_rows.append(d)
    self.make_sl_entries(sl_entries)
    # above method inserts the SLEs
    # stock_value_difference is made only after the above method

    # STOCK GL ENTRIES
    # Proceed if perpetual inventory is enabled
    import erpnext
    if not erpnext.is_perpetual_inventory_enabled(self.company):
        return

    #--- get stock ledger entries just made
    from erpnext.stock import get_warehouse_account_map
    warehouse_account = get_warehouse_account_map()
    sle_map = {}
    stock_ledger_entries = frappe.db.sql("""
		select
			name, warehouse, stock_value_difference, valuation_rate,
			voucher_detail_no, item_code, posting_date, posting_time,
			actual_qty, qty_after_transaction
		from
			`tabStock Ledger Entry`
		where
			voucher_type=%s and voucher_no=%s and parent=%s
	""", (self.doctype, self.name, "consoleerp-{}".format(self.name)),
                                         as_dict=True)

    for sle in stock_ledger_entries:
        sle_map.setdefault(sle.voucher_detail_no, []).append(sle)

    warehouse_with_no_account = []
    gl_list = []

    # loop it again
    # stock_controller.get_gl_entries()
    for item_row in changed_rows:
        sle_list = sle_map.get(item_row.name)
        if sle_list:
            for sle in sle_list:
                if warehouse_account.get(sle.warehouse):
                    # from warehouse account

                    self.check_expense_account(item_row)

                    # If the item does not have the allow zero valuation rate flag set
                    # and ( valuation rate not mentioned in an incoming entry
                    # or incoming entry not found while delivering the item),
                    # try to pick valuation rate from previous sle or Item master and update in SLE
                    # Otherwise, throw an exception

                    if not sle.stock_value_difference and self.doctype != "Stock Reconciliation" \
                     and not item_row.get("allow_zero_valuation_rate"):

                        sle = self.update_stock_ledger_entries(sle)

                    gl_list.append(
                        self.get_gl_dict(
                            {
                                "account":
                                warehouse_account[sle.warehouse]["account"],
                                "against":
                                item_row.expense_account,
                                "cost_center":
                                item_row.cost_center,
                                "remarks":
                                "Delivery Note Validation Entry",
                                "debit":
                                flt(sle.stock_value_difference, 2),
                            }, warehouse_account[sle.warehouse]
                            ["account_currency"]))

                    # to target warehouse / expense account
                    gl_list.append(
                        self.get_gl_dict({
                            "account":
                            item_row.expense_account,
                            "against":
                            warehouse_account[sle.warehouse]["account"],
                            "cost_center":
                            item_row.cost_center,
                            "remarks":
                            "Delivery Note Validation Entry",
                            "credit":
                            flt(sle.stock_value_difference, 2),
                            "project":
                            item_row.get("project") or self.get("project")
                        }))
                elif sle.warehouse not in warehouse_with_no_account:
                    warehouse_with_no_account.append(sle.warehouse)

    if warehouse_with_no_account:
        for wh in warehouse_with_no_account:
            if frappe.db.get_value("Warehouse", wh, "company"):
                frappe.throw(
                    _("Warehouse {0} is not linked to any account, please mention the account in  the warehouse record or set default inventory account in company {1}."
                      ).format(wh, self.company))

    from erpnext.accounts.general_ledger import process_gl_map
    gl_list = process_gl_map(gl_list)

    from erpnext.accounts.general_ledger import merge_similar_entries
    gl_list = merge_similar_entries(gl_list)

    self.make_gl_entries(gl_list)