| # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors |
| # License: GNU General Public License v3. See license.txt |
| |
| from __future__ import unicode_literals |
| import frappe |
| from frappe.utils import flt, cstr, cint |
| from frappe import _ |
| |
| from erpnext.stock.doctype.item.item import get_last_purchase_details |
| from erpnext.stock.doctype.item.item import validate_end_of_life |
| |
| def update_last_purchase_rate(doc, is_submit): |
| """updates last_purchase_rate in item table for each item""" |
| |
| import frappe.utils |
| this_purchase_date = frappe.utils.getdate(doc.get('posting_date') or doc.get('transaction_date')) |
| |
| for d in doc.get("items"): |
| # get last purchase details |
| last_purchase_details = get_last_purchase_details(d.item_code, doc.name) |
| |
| # compare last purchase date and this transaction's date |
| last_purchase_rate = None |
| if last_purchase_details and \ |
| (last_purchase_details.purchase_date > this_purchase_date): |
| last_purchase_rate = last_purchase_details['base_rate'] |
| elif is_submit == 1: |
| # even if this transaction is the latest one, it should be submitted |
| # for it to be considered for latest purchase rate |
| if flt(d.conversion_factor): |
| last_purchase_rate = flt(d.base_rate) / flt(d.conversion_factor) |
| else: |
| frappe.throw(_("UOM Conversion factor is required in row {0}").format(d.idx)) |
| |
| # update last purchsae rate |
| if last_purchase_rate: |
| frappe.db.sql("""update `tabItem` set last_purchase_rate = %s where name = %s""", |
| (flt(last_purchase_rate), d.item_code)) |
| |
| def validate_for_items(doc): |
| items = [] |
| for d in doc.get("items"): |
| if not d.qty: |
| if doc.doctype == "Purchase Receipt" and d.rejected_qty: |
| continue |
| frappe.throw(_("Please enter quantity for Item {0}").format(d.item_code)) |
| |
| # update with latest quantities |
| bin = frappe.db.sql("""select projected_qty from `tabBin` where |
| item_code = %s and warehouse = %s""", (d.item_code, d.warehouse), as_dict=1) |
| |
| f_lst ={'projected_qty': bin and flt(bin[0]['projected_qty']) or 0, 'ordered_qty': 0, 'received_qty' : 0} |
| if d.doctype in ('Purchase Receipt Item', 'Purchase Invoice Item'): |
| f_lst.pop('received_qty') |
| for x in f_lst : |
| if d.meta.get_field(x): |
| d.set(x, f_lst[x]) |
| |
| item = frappe.db.sql("""select is_stock_item, |
| is_sub_contracted_item, end_of_life, disabled from `tabItem` where name=%s""", |
| d.item_code, as_dict=1)[0] |
| |
| validate_end_of_life(d.item_code, item.end_of_life, item.disabled) |
| |
| # validate stock item |
| if item.is_stock_item==1 and d.qty and not d.warehouse and not d.delivered_by_supplier: |
| frappe.throw(_("Warehouse is mandatory for stock Item {0} in row {1}").format(d.item_code, d.idx)) |
| |
| items.append(cstr(d.item_code)) |
| |
| if items and len(items) != len(set(items)) and \ |
| not cint(frappe.db.get_single_value("Buying Settings", "allow_multiple_items") or 0): |
| frappe.throw(_("Same item cannot be entered multiple times.")) |
| |
| def check_for_closed_status(doctype, docname): |
| status = frappe.db.get_value(doctype, docname, "status") |
| |
| if status == "Closed": |
| frappe.throw(_("{0} {1} status is {2}").format(doctype, docname, status), frappe.InvalidStatusError) |
| |