<commit_before># ERPNext - web based ERP (http://erpnext.com)
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
# 
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

from __future__ import unicode_literals
import webnotes
from webnotes.utils import cint, flt, cstr
import webnotes.defaults
from controllers.accounts_controller import AccountsController

class StockController(AccountsController):
	def get_gl_entries_for_stock(self, against_stock_account, amount=None, 
			stock_in_hand_account=None, cost_center=None, warehouse_list=None):
		if not cost_center:
			cost_center = self.get_company_default("stock_adjustment_cost_center")
			
		acc_diff = {}
		if warehouse_list:
			from accounts.utils import get_stock_and_account_difference
			acc_diff = get_stock_and_account_difference(warehouse_list)
		elif amount and stock_in_hand_account:
			acc_diff = {stock_in_hand_account: amount}

		gl_entries = []
		for account, amount in acc_diff.items():
			gl_entries += [
				# stock in hand account
				self.get_gl_dict({
					"account": account,
					"against": against_stock_account,
					"debit": amount,
					"remarks": self.doc.remarks or "Accounting Entry for Stock",
				}, self.doc.docstatus == 2),
				
				# account against stock in hand
				self.get_gl_dict({
					"account": against_stock_account,
					"against": account,
					"credit": amount,
					"cost_center": cost_center or None,
					"remarks": self.doc.remarks or "Accounting Entry for Stock",
				}, self.doc.docstatus == 2),
			]
			
		return gl_entries
			
			
	def get_sl_entries(self, d, args):		
		sl_dict = {
			"item_code": d.item_code,
			"warehouse": d.warehouse,
			"posting_date": self.doc.posting_date,
			"posting_time": self.doc.posting_time,
			"voucher_type": self.doc.doctype,
			"voucher_no": self.doc.name,
			"voucher_detail_no": d.name,
			"actual_qty": (self.doc.docstatus==1 and 1 or -1)*flt(d.stock_qty),
			"stock_uom": d.stock_uom,
			"incoming_rate": 0,
			"company": self.doc.company,
			"fiscal_year": self.doc.fiscal_year,
			"is_cancelled": self.doc.docstatus==2 and "Yes" or "No",
			"batch_no": cstr(d.batch_no).strip(),
			"serial_no": d.serial_no,
			"project": d.project_name
		}
		
		sl_dict.update(args)
		return sl_dict
		
	def make_sl_entries(self, sl_entries, is_amended=None):
		if sl_entries:
			from webnotes.model.code import get_obj
			get_obj('Stock Ledger').update_stock(sl_entries, is_amended)
		
	def get_stock_ledger_entries(self, item_list=None, warehouse_list=None):
		if not (item_list and warehouse_list):
			item_list, warehouse_list = self.get_distinct_item_warehouse()
			
		if item_list and warehouse_list:
			return webnotes.conn.sql("""select item_code, voucher_type, voucher_no,
				voucher_detail_no, posting_date, posting_time, stock_value,
				warehouse, actual_qty as qty from `tabStock Ledger Entry` 
				where ifnull(`is_cancelled`, "No") = "No" and company = %s 
				and item_code in (%s) and warehouse in (%s)
				order by item_code desc, warehouse desc, posting_date desc, <commit_msg>[perpetual accounting] gl entry: sync stock and account balance<commit_after># ERPNext - web based ERP (http://erpnext.com)
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
# 
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

from __future__ import unicode_literals
import webnotes
from webnotes.utils import cint, flt, cstr
from webnotes import msgprint, _
import webnotes.defaults

from controllers.accounts_controller import AccountsController

class StockController(AccountsController):
	def get_gl_entries_for_stock(self, against_stock_account, amount, warehouse=None, 
			stock_in_hand_account=None, cost_center=None):
		if not stock_in_hand_account and warehouse:
			stock_in_hand_account = webnotes.conn.get_value("Warehouse", warehouse, "account")
		
		if amount:
			gl_entries = [
				# stock in hand account
				self.get_gl_dict({
					"account": stock_in_hand_account,
					"against": against_stock_account,
					"debit": amount,
					"remarks": self.doc.remarks or "Accounting Entry for Stock",
				}, self.doc.docstatus == 2),
				
				# account against stock in hand
				self.get_gl_dict({
					"account": against_stock_account,
					"against": stock_in_hand_account,
					"credit": amount,
					"cost_center": cost_center or None,
					"remarks": self.doc.remarks or "Accounting Entry for Stock",
				}, self.doc.docstatus == 2),
			]
			
			return gl_entries
			
	def sync_stock_account_balance(self, warehouse_list, cost_center=None, posting_date=None):
		from accounts.utils import get_stock_and_account_difference
		acc_diff = get_stock_and_account_difference(warehouse_list)
		
		if not cost_center:
			cost_center = self.get_company_default("cost_center")
		
		gl_entries = []
		for account, diff in acc_diff.items():
			if diff:
				stock_adjustment_account = self.get_company_default("stock_adjustment_account")
				gl_entries += self.get_gl_entries_for_stock(stock_adjustment_account, diff, 
					stock_in_hand_account=account, cost_center=cost_center)
					
		if gl_entries:
			from accounts.general_ledger import make_gl_entries

			if posting_date:
				for entries in gl_entries:
					entries["posting_date"] = posting_date
			
			make_gl_entries(gl_entries)
				
	def get_sl_entries(self, d, args):		
		sl_dict = {
			"item_code": d.item_code,
			"warehouse": d.warehouse,
			"posting_date": self.doc.posting_date,
			"posting_time": self.doc.posting_time,
			"voucher_type": self.doc.doctype,
			"voucher_no": self.doc.name,
			"voucher_detail_no": d.name,
			"actual_qty": (self.doc.docstatus==1 and 1 or -1)*flt(d.stock_qty),
			"stock_uom": d.stock_uom,
			"incoming_rate": 0,
			"company": self.doc.company,
			"fiscal_year": self.doc.fiscal_year,
			"is_cancelled": self.doc.docstatus==2 and "Yes" or "No",
			"batch_no": cstr(d.batch_no).strip(),
			"serial_no": d.serial_no,
			"project": d.project_name
		}
		
		sl_dict.update(args)
		return sl_dict
		
	def make_sl_entries(self, sl_entries, is_amended=None):
		if sl_entries:
			from webnotes.model.code import get_obj
			get_obj('Stock Ledger').update_stock(sl_entries, is_amended)
			
	def validate_warehouse_with_company(self, warehouse_list):
		warehouse_list = list(set(filter(lambda x: x not in ["", None], warehouse_list)))
		valid_warehouses = webnotes.conn.sql_list("""select name from `tabWarehouse` 
			where company=%s""", self.doc.company)
		
		invalid_warehouses = filter(lambda x: x not in valid_warehouses, warehouse_list)
		if invalid_warehouses:
			print invalid_warehouses, valid_warehouses, warehouse_list
			msgprint(_("Following warehouses not belong to the company") + ": " + 
				self.doc.company + "\n" + "\n".join(invalid_warehouses), raise_exception=1)
		
	def get_stock_ledger_entries(self, item_list=None, warehouse_list=None):
		if not (item_list and warehouse_list):
			item_list, warehouse_list = self.get_distinct_item_warehouse()
			
		if item_list and warehouse_list:
			return webnotes.conn.sql("""select item_code, voucher_type, voucher_no,
				voucher_detail_no, posting_date, posting_time, stock_value,
				warehouse, actual_qty as qty from `tabStock Ledger Entry` 
				where ifnull(`is_cancelled`, "No") = "No" and company = %s 
				and item_code in (%s) and warehouse in (%s)
				order by item_code desc, warehouse desc, posting_date desc, 
{'fraction_non_alphanumeric': 0.09744013212221304, 'fraction_numerical': 0.0029491565412292082, 'mean_word_length': 4.4276568501920615, 'pattern_counts': {'":': 51, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4715492', 'n_tokens_mistral': 3187, 'n_tokens_neox': 2748, 'n_words': 750}