Example #1
0
def validate_account_for_perpetual_inventory(gl_map):
    if cint(erpnext.is_perpetual_inventory_enabled(gl_map[0].company)):
        account_list = [gl_entries.account for gl_entries in gl_map]

        aii_accounts = [
            d.name for d in frappe.get_all("Account",
                                           filters={
                                               'account_type': 'Stock',
                                               'is_group': 0,
                                               'company': gl_map[0].company
                                           })
        ]

        for account in account_list:
            if account not in aii_accounts:
                continue

            account_bal, stock_bal, warehouse_list = get_stock_and_account_balance(
                account, gl_map[0].posting_date, gl_map[0].company)

            if gl_map[0].voucher_type == "Journal Entry":
                # In case of Journal Entry, there are no corresponding SL entries,
                # hence deducting currency amount
                account_bal -= flt(gl_map[0].debit) - flt(gl_map[0].credit)
                if account_bal == stock_bal:
                    frappe.throw(
                        _("Account: {0} can only be updated via Stock Transactions"
                          ).format(account), StockAccountInvalidTransaction)
Example #2
0
	def _test_reco_sle_gle(self, valuation_method):
		insert_existing_sle(warehouse='Stores - TCP1')
		company = frappe.db.get_value('Warehouse', 'Stores - TCP1', 'company')
		# [[qty, valuation_rate, posting_date,
		#		posting_time, expected_stock_value, bin_qty, bin_valuation]]
		input_data = [
			[50, 1000, "2012-12-26", "12:00"],
			[25, 900, "2012-12-26", "12:00"],
			["", 1000, "2012-12-20", "12:05"],
			[20, "", "2012-12-26", "12:05"],
			[0, "", "2012-12-31", "12:10"]
		]

		for d in input_data:
			set_valuation_method("_Test Item", valuation_method)

			last_sle = get_previous_sle({
				"item_code": "_Test Item",
				"warehouse": "Stores - TCP1",
				"posting_date": d[2],
				"posting_time": d[3]
			})

			# submit stock reconciliation
			stock_reco = create_stock_reconciliation(qty=d[0], rate=d[1],
				posting_date=d[2], posting_time=d[3], warehouse="Stores - TCP1",
				company=company, expense_account = "Stock Adjustment - TCP1")

			# check stock value
			sle = frappe.db.sql("""select * from `tabStock Ledger Entry`
				where voucher_type='Stock Reconciliation' and voucher_no=%s""", stock_reco.name, as_dict=1)

			qty_after_transaction = flt(d[0]) if d[0] != "" else flt(last_sle.get("qty_after_transaction"))

			valuation_rate = flt(d[1]) if d[1] != "" else flt(last_sle.get("valuation_rate"))

			if qty_after_transaction == last_sle.get("qty_after_transaction") \
				and valuation_rate == last_sle.get("valuation_rate"):
					self.assertFalse(sle)
			else:
				self.assertEqual(sle[0].qty_after_transaction, qty_after_transaction)
				self.assertEqual(sle[0].stock_value, qty_after_transaction * valuation_rate)

				# no gl entries
				self.assertTrue(frappe.db.get_value("Stock Ledger Entry",
					{"voucher_type": "Stock Reconciliation", "voucher_no": stock_reco.name}))

				acc_bal, stock_bal, wh_list = get_stock_and_account_balance("Stock In Hand - TCP1",
					stock_reco.posting_date, stock_reco.company)
				self.assertEqual(acc_bal, stock_bal)

				stock_reco.cancel()

				self.assertFalse(frappe.db.get_value("Stock Ledger Entry",
					{"voucher_type": "Stock Reconciliation", "voucher_no": stock_reco.name}))

				self.assertFalse(frappe.db.get_value("GL Entry",
					{"voucher_type": "Stock Reconciliation", "voucher_no": stock_reco.name}))
Example #3
0
	def validate_stock_accounts(self):
		stock_accounts = get_stock_accounts(self.company, self.doctype, self.name)
		for account in stock_accounts:
			account_bal, stock_bal, warehouse_list = get_stock_and_account_balance(account,
				self.posting_date, self.company)

			if account_bal == stock_bal:
				frappe.throw(_("Account: {0} can only be updated via Stock Transactions")
					.format(account), StockAccountInvalidTransaction)
Example #4
0
def validate_account_for_perpetual_inventory(gl_map):
	if cint(erpnext.is_perpetual_inventory_enabled(gl_map[0].company)):
		account_list = [gl_entries.account for gl_entries in gl_map]

		aii_accounts = [d.name for d in frappe.get_all("Account",
			filters={'account_type': 'Stock', 'is_group': 0, 'company': gl_map[0].company})]

		for account in account_list:
			if account not in aii_accounts:
				continue

			# Always use current date to get stock and account balance as there can future entries for
			# other items
			account_bal, stock_bal, warehouse_list = get_stock_and_account_balance(account,
				getdate(), gl_map[0].company)

			if gl_map[0].voucher_type=="Journal Entry":
				# In case of Journal Entry, there are no corresponding SL entries,
				# hence deducting currency amount
				account_bal -= flt(gl_map[0].debit) - flt(gl_map[0].credit)
				if account_bal == stock_bal:
					frappe.throw(_("Account: {0} can only be updated via Stock Transactions")
						.format(account), StockAccountInvalidTransaction)

			elif abs(account_bal - stock_bal) > 0.1:
				precision = get_field_precision(frappe.get_meta("GL Entry").get_field("debit"),
					currency=frappe.get_cached_value('Company',  gl_map[0].company,  "default_currency"))

				diff = flt(stock_bal - account_bal, precision)
				error_reason = _("Stock Value ({0}) and Account Balance ({1}) are out of sync for account {2} and it's linked warehouses.").format(
					stock_bal, account_bal, frappe.bold(account))
				error_resolution = _("Please create adjustment Journal Entry for amount {0} ").format(frappe.bold(diff))
				stock_adjustment_account = frappe.db.get_value("Company",gl_map[0].company,"stock_adjustment_account")

				db_or_cr_warehouse_account =('credit_in_account_currency' if diff < 0 else 'debit_in_account_currency')
				db_or_cr_stock_adjustment_account = ('debit_in_account_currency' if diff < 0 else 'credit_in_account_currency')

				journal_entry_args = {
				'accounts':[
					{'account': account, db_or_cr_warehouse_account : abs(diff)},
					{'account': stock_adjustment_account, db_or_cr_stock_adjustment_account : abs(diff) }]
				}

				frappe.msgprint(msg="""{0}<br></br>{1}<br></br>""".format(error_reason, error_resolution),
					raise_exception=StockValueAndAccountBalanceOutOfSync,
					title=_('Values Out Of Sync'),
					primary_action={
						'label': _('Make Journal Entry'),
						'client_action': 'erpnext.route_to_adjustment_jv',
						'args': journal_entry_args
					})
Example #5
0
    def test_jv_against_stock_account(self):
        company = "_Test Company with perpetual inventory"
        stock_account = get_inventory_account(company)

        from erpnext.accounts.utils import get_stock_and_account_balance

        account_bal, stock_bal, warehouse_list = get_stock_and_account_balance(
            stock_account, nowdate(), company)
        diff = flt(account_bal) - flt(stock_bal)

        if not diff:
            diff = 100

        jv = frappe.new_doc("Journal Entry")
        jv.company = company
        jv.posting_date = nowdate()
        jv.append(
            "accounts",
            {
                "account": stock_account,
                "cost_center": "Main - TCP1",
                "debit_in_account_currency": 0 if diff > 0 else abs(diff),
                "credit_in_account_currency": diff if diff > 0 else 0,
            },
        )

        jv.append(
            "accounts",
            {
                "account": "Stock Adjustment - TCP1",
                "cost_center": "Main - TCP1",
                "debit_in_account_currency": diff if diff > 0 else 0,
                "credit_in_account_currency": 0 if diff > 0 else abs(diff),
            },
        )
        jv.insert()

        if account_bal == stock_bal:
            self.assertRaises(StockAccountInvalidTransaction, jv.submit)
            frappe.db.rollback()
        else:
            jv.submit()
            jv.cancel()
def get_unsync_date(filters):
    date = filters.from_date
    if not date:
        date = frappe.db.sql(
            """ SELECT min(posting_date) from `tabStock Ledger Entry`""")
        date = date[0][0]

    if not date:
        return

    while getdate(date) < getdate(today()):
        account_bal, stock_bal, warehouse_list = get_stock_and_account_balance(
            posting_date=date,
            company=filters.company,
            account=filters.account)

        if abs(account_bal - stock_bal) > 0.1:
            return date

        date = add_days(date, 1)