Esempio n. 1
0
def update_gl_entries_after(posting_date,
                            posting_time,
                            for_warehouses=None,
                            for_items=None,
                            warehouse_account=None,
                            company=None):
    def _delete_gl_entries(voucher_type, voucher_no):
        dataent.db.sql(
            """delete from `tabGL Entry`
			where voucher_type=%s and voucher_no=%s""", (voucher_type, voucher_no))

    if not warehouse_account:
        warehouse_account = get_warehouse_account_map(company)

    future_stock_vouchers = get_future_stock_vouchers(posting_date,
                                                      posting_time,
                                                      for_warehouses,
                                                      for_items)
    gle = get_voucherwise_gl_entries(future_stock_vouchers, posting_date)

    for voucher_type, voucher_no in future_stock_vouchers:
        existing_gle = gle.get((voucher_type, voucher_no), [])
        voucher_obj = dataent.get_doc(voucher_type, voucher_no)
        expected_gle = voucher_obj.get_gl_entries(warehouse_account)
        if expected_gle:
            if not existing_gle or not compare_existing_and_expected_gle(
                    existing_gle, expected_gle):
                _delete_gl_entries(voucher_type, voucher_no)
                voucher_obj.make_gl_entries(gl_entries=expected_gle,
                                            repost_future_gle=False,
                                            from_repost=True)
        else:
            _delete_gl_entries(voucher_type, voucher_no)
def execute():
    company_list = dataent.db.sql_list(
        """Select name from tabCompany where enable_perpetual_inventory = 1""")
    dataent.reload_doc('accounts', 'doctype', 'sales_invoice')

    dataent.reload_doctype("Purchase Invoice")
    wh_account = get_warehouse_account_map()

    for pi in dataent.get_all("Purchase Invoice",
                              fields=["name", "company"],
                              filters={
                                  "docstatus": 1,
                                  "update_stock": 1
                              }):
        if pi.company in company_list:
            pi_doc = dataent.get_doc("Purchase Invoice", pi.name)
            items, warehouses = pi_doc.get_items_and_warehouses()
            update_gl_entries_after(pi_doc.posting_date,
                                    pi_doc.posting_time,
                                    warehouses,
                                    items,
                                    wh_account,
                                    company=pi.company)

            dataent.db.commit()
Esempio n. 3
0
    def make_gl_entries(self,
                        gl_entries=None,
                        repost_future_gle=True,
                        from_repost=False):
        if self.docstatus == 2:
            delete_gl_entries(voucher_type=self.doctype, voucher_no=self.name)

        if cint(epaas.is_perpetual_inventory_enabled(self.company)):
            warehouse_account = get_warehouse_account_map(self.company)

            if self.docstatus == 1:
                if not gl_entries:
                    gl_entries = self.get_gl_entries(warehouse_account)
                make_gl_entries(gl_entries, from_repost=from_repost)

            if repost_future_gle:
                items, warehouses = self.get_items_and_warehouses()
                update_gl_entries_after(self.posting_date,
                                        self.posting_time,
                                        warehouses,
                                        items,
                                        warehouse_account,
                                        company=self.company)
        elif self.doctype in ['Purchase Receipt', 'Purchase Invoice'
                              ] and self.docstatus == 1:
            gl_entries = []
            gl_entries = self.get_asset_gl_entry(gl_entries)
            make_gl_entries(gl_entries, from_repost=from_repost)
Esempio n. 4
0
def get_stock_and_account_difference(account_list=None, posting_date=None, company=None):
	from epaas.stock.utils import get_stock_value_on
	from epaas.stock import get_warehouse_account_map

	if not posting_date: posting_date = nowdate()

	difference = {}
	warehouse_account = get_warehouse_account_map(company)

	for warehouse, account_data in iteritems(warehouse_account):
		if account_data.get('account') in account_list:
			account_balance = get_balance_on(account_data.get('account'), posting_date, in_account_currency=False)
			stock_value = get_stock_value_on(warehouse, posting_date)
			if abs(flt(stock_value) - flt(account_balance)) > 0.005:
				difference.setdefault(account_data.get('account'), flt(stock_value) - flt(account_balance))

	return difference
Esempio n. 5
0
	def set_expense_account(self, for_validate=False):
		auto_accounting_for_stock = epaas.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 dataent.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:
					dataent.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))
Esempio n. 6
0
	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)

		voucher_wise_stock_value = {}
		if self.update_stock:
			for d in dataent.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)

		for item in self.get("items"):
			if flt(item.base_net_amount):
				account_currency = get_account_currency(item.expense_account)

				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
						}, account_currency)
					)

					# Amount added through landed-cost-voucher
					if flt(item.landed_cost_voucher_amount):
						gl_entries.append(self.get_gl_dict({
							"account": expenses_included_in_valuation,
							"against": item.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
						}))

					# sub-contracting warehouse
					if flt(item.rm_supp_cost):
						supplier_warehouse_account = warehouse_account[self.supplier_warehouse]["account"]
						if not supplier_warehouse_account:
							dataent.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,
							"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
							"credit": flt(item.rm_supp_cost)
						}, warehouse_account[self.supplier_warehouse]["account_currency"]))
				elif not item.is_fixed_asset or (item.is_fixed_asset and is_cwip_accounting_disabled()):
					gl_entries.append(
						self.get_gl_dict({
							"account": item.expense_account if not item.enable_deferred_expense else item.deferred_expense_account,
							"against": self.supplier,
							"debit": flt(item.base_net_amount, item.precision("base_net_amount")),
							"debit_in_account_currency": (flt(item.base_net_amount,
								item.precision("base_net_amount")) if account_currency==self.company_currency
								else flt(item.net_amount, item.precision("net_amount"))),
							"cost_center": item.cost_center,
							"project": item.project
						}, account_currency)
					)

			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:
						negative_expense_booked_in_pr = dataent.db.sql("""select name from `tabGL Entry`
							where voucher_type='Purchase Receipt' and voucher_no=%s and account=%s""",
							(item.purchase_receipt, self.expenses_included_in_valuation))

						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
								})
							)

							self.negative_expense_to_be_booked += flt(item.item_tax_amount, \
								item.precision("item_tax_amount"))
Esempio n. 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),
                                    "is_opening":
                                    item_row.get("is_opening")
                                    or self.get("is_opening") or "No",
                                }, 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"),
                                "is_opening":
                                item_row.get("is_opening")
                                or self.get("is_opening") or "No"
                            }))
                    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 dataent.db.get_value("Warehouse", wh, "company"):
                    dataent.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)