# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
# License: GNU General Public License v3. See license.txt

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
from accounts.general_ledger import make_gl_entries, delete_gl_entries

class StockController(AccountsController):
	def make_gl_entries(self):
		if not cint(webnotes.defaults.get_global_default("auto_accounting_for_stock")):
			return
		
		warehouse_account = self.get_warehouse_account()
		
		if self.doc.docstatus==1:
			gl_entries = self.get_gl_entries_for_stock(warehouse_account)
			make_gl_entries(gl_entries)
		else:	
			delete_gl_entries(voucher_type=self.doc.doctype, voucher_no=self.doc.name)
		
		self.update_gl_entries_after(warehouse_account)
	
	def get_gl_entries_for_stock(self, warehouse_account=None, default_expense_account=None,
			default_cost_center=None):
		from accounts.general_ledger import process_gl_map
		if not warehouse_account:
			warehouse_account = self.get_warehouse_account()
		
		stock_ledger = self.get_stock_ledger_details()
		voucher_details = self.get_voucher_details(stock_ledger, default_expense_account, 
			default_cost_center)
		
		gl_list = []
		warehouse_with_no_account = []
		for detail in voucher_details:
			sle_list = stock_ledger.get(detail.name)
			if sle_list:
				for sle in sle_list:
					if warehouse_account.get(sle.warehouse):
						# from warehouse account
						gl_list.append(self.get_gl_dict({
							"account": warehouse_account[sle.warehouse],
							"against": detail.expense_account,
							"cost_center": detail.cost_center,
							"remarks": self.doc.remarks or "Accounting Entry for Stock",
							"debit": sle.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.doc.remarks or "Accounting Entry for Stock",
							"credit": sle.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 following warehouses") + ": \n" + 
				"\n".join(warehouse_with_no_account))
		
		return process_gl_map(gl_list)
			
	def get_voucher_details(self, stock_ledger, default_expense_account, default_cost_center):
		if not default_expense_account:
			details = self.doclist.get({"parentfield": self.fname})
			for d in details:
				self.check_expense_account(d)
		else:
			details = [webnotes._dict({
				"name":d, 
				"expense_account": default_expense_account, 
				"cost_center": default_cost_center
			}) for d in stock_ledger.keys()]
			
		return details
		
	def get_stock_ledger_details(self):
		stock_ledger = {}
		for sle in webnotes.conn.sql("""select warehouse, stock_value_difference, voucher_detail_no
			from `tabStock Ledger Entry` where voucher_type=%s and voucher_no=%s""",
			(self.doc.doctype, self.doc.name), as_dict=True):
				stock_ledger.setdefault(sle.voucher_detail_no, []).append(sle)
		return stock_ledger
		
	def get_warehouse_account(self):
		for d in webnotes.conn.sql("select name from tabWarehouse"):
			webnotes.bean("Warehouse", d[0]).save()

		warehouse_account = dict(webnotes.conn.sql("""select master_name, name from tabAccount 
			where account_type = 'Warehouse' and ifnull(master_name, '') != ''"""))
		return warehouse_account
		
	def update_gl_entries_after(self, warehouse_account=None):
		future_stock_vouchers = self.get_future_stock_vouchers()
		gle = self.get_voucherwise_gl_entries(future_stock_vouchers)
		if not warehouse_account:
			warehouse_account = self.get_warehouse_account()
		
		for voucher_type, voucher_no in future_stock_vouchers:
			existing_gle = gle.get((voucher_type, voucher_no), [])
			voucher_obj = webnotes.get_obj(voucher_type, voucher_no)
			expected_gle = voucher_obj.get_gl_entries_for_stock(warehouse_account)
			
			if expected_gle:
				matched = True
				if existing_gle:
					for entry in expected_gle:
						for e in existing_gle:
							if entry.account==e.account \
								and entry.against_account==e.against_account\
								and entry.cost_center==e.cost_center:
									if entry.debit != e.debit or entry.credit != e.credit:
										matched = False
										break
				else:
					matched = False
									
				if not matched:
					self.delete_gl_entries(voucher_type, voucher_no)
					make_gl_entries(expected_gle)
			else:
				self.delete_gl_entries(voucher_type, voucher_no)
				
		
	def get_future_stock_vouchers(self):
		future_stock_vouchers = []
		
		if hasattr(self, "fname"):
			item_list = [d.item_code for d in self.doclist.get({"parentfield": self.fname})]
			condition = ''.join(['and item_code in (\'', '\', \''.join(item_list) ,'\')'])
		else:
			condition = ""
		
		for d in webnotes.conn.sql("""select distinct sle.voucher_type, sle.voucher_no 
			from `tabStock Ledger Entry` sle
			where timestamp(sle.posting_date, sle.posting_time) >= timestamp(%s, %s) %s
			order by timestamp(sle.posting_date, sle.posting_time) asc, name asc""" % 
			('%s', '%s', condition), (self.doc.posting_date, self.doc.posting_time), 
			as_dict=True):
				future_stock_vouchers.append([d.voucher_type, d.voucher_no])
		
		return future_stock_vouchers
				
	def get_voucherwise_gl_entries(self, future_stock_vouchers):
		gl_entries = {}
		if future_stock_vouchers:
			for d in webnotes.conn.sql("""select * from `tabGL Entry` 
				where posting_date >= %s and voucher_no in (%s)""" % 
				('%s', ', '.join(['%s']*len(future_stock_vouchers))), 
				tuple([self.doc.posting_date] + [d[1] for d in future_stock_vouchers]), as_dict=1):
					gl_entries.setdefault((d.voucher_type, d.voucher_no), []).append(d)
		
		return gl_entries
		
	def delete_gl_entries(self, voucher_type, voucher_no):
		webnotes.conn.sql("""delete from `tabGL Entry` 
			where voucher_type=%s and voucher_no=%s""", (voucher_type, voucher_no))
					
	def make_adjustment_entry(self, expected_gle, voucher_obj):
		from accounts.utils import get_stock_and_account_difference
		account_list = [d.account for d in expected_gle]
		acc_diff = get_stock_and_account_difference(account_list, expected_gle[0].posting_date)
		
		cost_center = self.get_company_default("cost_center")
		stock_adjustment_account = self.get_company_default("stock_adjustment_account")

		gl_entries = []
		for account, diff in acc_diff.items():
			if diff:
				gl_entries.append([
					# stock in hand account
					voucher_obj.get_gl_dict({
						"account": account,
						"against": stock_adjustment_account,
						"debit": diff,
						"remarks": "Adjustment Accounting Entry for Stock",
					}),
				
					# account against stock in hand
					voucher_obj.get_gl_dict({
						"account": stock_adjustment_account,
						"against": account,
						"credit": diff,
						"cost_center": cost_center or None,
						"remarks": "Adjustment Accounting Entry for Stock",
					}),
				])
				
		if gl_entries:
			from accounts.general_ledger import make_gl_entries
			make_gl_entries(gl_entries)
			
	def check_expense_account(self, item):
		if item.fields.has_key("expense_account") and not item.expense_account:
			msgprint(_("""Expense/Difference account is mandatory for item: """) + item.item_code, 
				raise_exception=1)
				
		if item.fields.has_key("expense_account") and not item.cost_center:
			msgprint(_("""Cost Center is mandatory for item: """) + item.item_code, 
				raise_exception=1)
				
	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,
			"batch_no": cstr(d.batch_no).strip(),
			"serial_no": d.serial_no,
			"project": d.project_name,
			"is_cancelled": self.doc.docstatus==2 and "Yes" or "No"
		}
		
		sl_dict.update(args)
		return sl_dict
		
	def make_sl_entries(self, sl_entries, is_amended=None):
		from stock.stock_ledger import make_sl_entries
		make_sl_entries(sl_entries, is_amended)
		
	def get_stock_ledger_entries(self, item_list=None, warehouse_list=None):
		out = {}
		
		if not (item_list and warehouse_list):
			item_list, warehouse_list = self.get_distinct_item_warehouse()
			
		if item_list and warehouse_list:
			res = 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 company = %s and item_code in (%s) and warehouse in (%s)
				order by item_code desc, warehouse desc, posting_date desc, 
				posting_time desc, name desc""" % 
				('%s', ', '.join(['%s']*len(item_list)), ', '.join(['%s']*len(warehouse_list))), 
				tuple([self.doc.company] + item_list + warehouse_list), as_dict=1)
				
			for r in res:
				if (r.item_code, r.warehouse) not in out:
					out[(r.item_code, r.warehouse)] = []
		
				out[(r.item_code, r.warehouse)].append(r)

		return out

	def get_distinct_item_warehouse(self):
		item_list = []
		warehouse_list = []
		for item in self.doclist.get({"parentfield": self.fname}) \
				+ self.doclist.get({"parentfield": "packing_details"}):
			item_list.append(item.item_code)
			warehouse_list.append(item.warehouse)
			
		return list(set(item_list)), list(set(warehouse_list))
		
	def make_cancel_gl_entries(self):
		if webnotes.conn.sql("""select name from `tabGL Entry` where voucher_type=%s 
			and voucher_no=%s""", (self.doc.doctype, self.doc.name)):
				self.make_gl_entries()