def make_sl_entries(sl_entries, is_amended=None, allow_negative_stock=False, via_landed_cost_voucher=False): if sl_entries: from erpnext.stock.utils import update_bin cancel = True if sl_entries[0].get("is_cancelled") == "Yes" else False if cancel: set_as_cancel(sl_entries[0].get('voucher_no'), sl_entries[0].get('voucher_type')) for sle in sl_entries: sle_id = None if sle.get('is_cancelled') == 'Yes': sle['actual_qty'] = -flt(sle['actual_qty']) if sle.get("actual_qty") or sle.get("voucher_type")=="Stock Reconciliation": sle_id = make_entry(sle, allow_negative_stock, via_landed_cost_voucher) args = sle.copy() args.update({ "sle_id": sle_id, "is_amended": is_amended }) update_bin(args, allow_negative_stock, via_landed_cost_voucher) if cancel: delete_cancelled_entry(sl_entries[0].get('voucher_type'), sl_entries[0].get('voucher_no'))
def make_sl_entries(sl_entries, allow_negative_stock=False, via_landed_cost_voucher=False): if sl_entries: from erpnext.stock.utils import update_bin cancel = sl_entries[0].get("is_cancelled") if cancel: validate_cancellation(sl_entries) set_as_cancel(sl_entries[0].get('voucher_type'), sl_entries[0].get('voucher_no')) for sle in sl_entries: if cancel: sle['actual_qty'] = -flt(sle.get('actual_qty')) if sle['actual_qty'] < 0 and not sle.get('outgoing_rate'): sle['outgoing_rate'] = get_incoming_outgoing_rate_for_cancel( sle.item_code, sle.voucher_type, sle.voucher_no, sle.voucher_detail_no) sle['incoming_rate'] = 0.0 if sle['actual_qty'] > 0 and not sle.get('incoming_rate'): sle['incoming_rate'] = get_incoming_outgoing_rate_for_cancel( sle.item_code, sle.voucher_type, sle.voucher_no, sle.voucher_detail_no) sle['outgoing_rate'] = 0.0 if sle.get("actual_qty") or sle.get( "voucher_type") == "Stock Reconciliation": sle_doc = make_entry(sle, allow_negative_stock, via_landed_cost_voucher) args = sle_doc.as_dict() update_bin(args, allow_negative_stock, via_landed_cost_voucher)
def make_sl_entries(sl_entries, is_amended=None): if sl_entries: from erpnext.stock.utils import update_bin cancel = True if sl_entries[0].get("is_cancelled") == "Yes" else False if cancel: set_as_cancel(sl_entries[0].get('voucher_no'), sl_entries[0].get('voucher_type')) for sle in sl_entries: sle_id = None if sle.get('is_cancelled') == 'Yes': sle['actual_qty'] = -flt(sle['actual_qty']) if sle.get("actual_qty") or sle.get( "voucher_type") == "Stock Reconciliation": sle_id = make_entry(sle) args = sle.copy() args.update({"sle_id": sle_id, "is_amended": is_amended}) update_bin(args) if cancel: delete_cancelled_entry(sl_entries[0].get('voucher_type'), sl_entries[0].get('voucher_no'))
def update_ordered_qty(self): stock_items = self.get_stock_items() for d in self.doclist.get({"parentfield": "purchase_receipt_details"}): if d.item_code in stock_items and d.warehouse \ and cstr(d.prevdoc_doctype) == 'Purchase Order': already_received_qty = self.get_already_received_qty( d.prevdoc_docname, d.prevdoc_detail_docname) po_qty, ordered_warehouse = self.get_po_qty_and_warehouse( d.prevdoc_detail_docname) if not ordered_warehouse: frappe.throw(_("Warehouse is missing in Purchase Order")) if already_received_qty + d.qty > po_qty: ordered_qty = -(po_qty - already_received_qty) * flt( d.conversion_factor) else: ordered_qty = -flt(d.qty) * flt(d.conversion_factor) update_bin({ "item_code": d.item_code, "warehouse": ordered_warehouse, "posting_date": self.doc.posting_date, "ordered_qty": flt(ordered_qty) if self.doc.docstatus == 1 else -flt(ordered_qty) })
def make_slentries(self,sl_entries, is_amended=None, allow_negative_stock=False, via_landed_cost_voucher=False): if sl_entries: from erpnext.stock.utils import update_bin cancel = True if sl_entries[0].get("is_cancelled") == "Yes" else False if cancel: set_as_cancel(sl_entries[0].get('voucher_no'), sl_entries[0].get('voucher_type')) for sle in sl_entries: sle_id = None if sle.get('is_cancelled') == 'Yes': sle['actual_qty'] = -flt(sle['actual_qty']) print("actual_qtd ",sle.actual_qty) if sle.get("actual_qty") or sle.get("voucher_type")=="Stock Reconciliation": print ("FAZ Entry") print (sle) print (via_landed_cost_voucher) sle_id = self.make_entry(sle, allow_negative_stock, via_landed_cost_voucher) args = sle.copy() args.update({ "sle_id": sle_id, "is_amended": is_amended }) update_bin(args, allow_negative_stock, via_landed_cost_voucher) if cancel: delete_cancelled_entry(sl_entries[0].get('voucher_type'), sl_entries[0].get('voucher_no'))
def _update_requested_qty(doc, mr_obj, mr_items): """update requested qty (before ordered_qty is updated)""" from erpnext.stock.utils import update_bin for mr_item_name in mr_items: mr_item = mr_obj.get("indent_details", {"name": mr_item_name}) se_detail = doc.get("mtn_details", {"material_request": mr_obj.name, "material_request_item": mr_item_name}) if mr_item and se_detail: mr_item = mr_item[0] se_detail = se_detail[0] mr_item.ordered_qty = flt(mr_item.ordered_qty) mr_item.qty = flt(mr_item.qty) se_detail.transfer_qty = flt(se_detail.transfer_qty) if se_detail.docstatus == 2 and mr_item.ordered_qty > mr_item.qty \ and se_detail.transfer_qty == mr_item.ordered_qty: add_indented_qty = mr_item.qty elif se_detail.docstatus == 1 and \ mr_item.ordered_qty + se_detail.transfer_qty > mr_item.qty: add_indented_qty = mr_item.qty - mr_item.ordered_qty else: add_indented_qty = se_detail.transfer_qty update_bin({ "item_code": se_detail.item_code, "warehouse": se_detail.t_warehouse, "indented_qty": (se_detail.docstatus==2 and 1 or -1) * add_indented_qty, "posting_date": doc.posting_date, })
def _update_requested_qty(bean, mr_obj, mr_items): """update requested qty (before ordered_qty is updated)""" from erpnext.stock.utils import update_bin for mr_item_name in mr_items: mr_item = mr_obj.doclist.getone({ "parentfield": "indent_details", "name": mr_item_name }) se_detail = bean.doclist.getone({ "parentfield": "mtn_details", "material_request": mr_obj.doc.name, "material_request_item": mr_item_name }) mr_item.ordered_qty = flt(mr_item.ordered_qty) mr_item.qty = flt(mr_item.qty) se_detail.transfer_qty = flt(se_detail.transfer_qty) if se_detail.docstatus == 2 and mr_item.ordered_qty > mr_item.qty \ and se_detail.transfer_qty == mr_item.ordered_qty: add_indented_qty = mr_item.qty elif se_detail.docstatus == 1 and \ mr_item.ordered_qty + se_detail.transfer_qty > mr_item.qty: add_indented_qty = mr_item.qty - mr_item.ordered_qty else: add_indented_qty = se_detail.transfer_qty update_bin({ "item_code": se_detail.item_code, "warehouse": se_detail.t_warehouse, "indented_qty": (se_detail.docstatus == 2 and 1 or -1) * add_indented_qty, "posting_date": bean.doc.posting_date, })
def radpp_make_sl_entries(self, sl_entries, is_amended=None, allow_negative_stock=False, via_landed_cost_voucher=False): if sl_entries: from erpnext.stock.utils import update_bin from erpnext.stock.stock_ledger import make_entry, set_as_cancel, delete_cancelled_entry cancel = True if sl_entries[0].get("is_cancelled") == "Yes" else False if cancel: set_as_cancel(sl_entries[0].get('voucher_no'), sl_entries[0].get('voucher_type')) for sle in sl_entries: sle_id = None if sle.get('is_cancelled') == 'Yes': sle['actual_qty'] = -flt(sle['actual_qty']) #if sle.get("actual_qty") or sle.get("voucher_type")=="Batch Stock Reconciliation": # frappe.msgprint("make_entry: ") sle_id = self.radpp_make_entry(sle, allow_negative_stock, via_landed_cost_voucher) args = sle.copy() args.update({ "sle_id": sle_id, "is_amended": is_amended }) update_bin(args, allow_negative_stock, via_landed_cost_voucher) if cancel: delete_cancelled_entry(sl_entries[0].get('voucher_type'), sl_entries[0].get('voucher_no'))
def set_stock_balance_as_per_serial_no(item_code=None, posting_date=None, posting_time=None, fiscal_year=None): if not posting_date: posting_date = nowdate() if not posting_time: posting_time = nowtime() condition = " and item.name='%s'" % item_code.replace("'", "\'") if item_code else "" bin = frappe.db.sql("""select bin.item_code, bin.warehouse, bin.actual_qty, item.stock_uom from `tabBin` bin, tabItem item where bin.item_code = item.name and item.has_serial_no = 1 %s""" % condition) for d in bin: serial_nos = frappe.db.sql("""select count(name) from `tabSerial No` where item_code=%s and warehouse=%s and docstatus < 2""", (d[0], d[1])) if serial_nos and flt(serial_nos[0][0]) != flt(d[2]): print(d[0], d[1], d[2], serial_nos[0][0]) sle = frappe.db.sql("""select valuation_rate, company from `tabStock Ledger Entry` where item_code = %s and warehouse = %s and ifnull(is_cancelled, 'No') = 'No' order by posting_date desc limit 1""", (d[0], d[1])) sle_dict = { 'doctype' : 'Stock Ledger Entry', 'item_code' : d[0], 'warehouse' : d[1], 'transaction_date' : nowdate(), 'posting_date' : posting_date, 'posting_time' : posting_time, 'voucher_type' : 'Stock Reconciliation (Manual)', 'voucher_no' : '', 'voucher_detail_no' : '', 'actual_qty' : flt(serial_nos[0][0]) - flt(d[2]), 'stock_uom' : d[3], 'incoming_rate' : sle and flt(serial_nos[0][0]) > flt(d[2]) and flt(sle[0][0]) or 0, 'company' : sle and cstr(sle[0][1]) or 0, 'is_cancelled' : 'No', 'batch_no' : '', 'serial_no' : '' } sle_doc = frappe.get_doc(sle_dict) sle_doc.flags.ignore_validate = True sle_doc.flags.ignore_links = True sle_doc.insert() args = sle_dict.copy() args.update({ "sle_id": sle_doc.name, "is_amended": 'No' }) update_bin(args) update_entries_after({ "item_code": d[0], "warehouse": d[1], "posting_date": posting_date, "posting_time": posting_time })
def set_stock_balance_as_per_serial_no(item_code=None, posting_date=None, posting_time=None, fiscal_year=None): if not posting_date: posting_date = nowdate() if not posting_time: posting_time = nowtime() condition = " and item.name='%s'" % item_code.replace("'", "\'") if item_code else "" bin = frappe.db.sql("""select bin.item_code, bin.warehouse, bin.actual_qty, item.stock_uom from `tabBin` bin, tabItem item where bin.item_code = item.name and item.has_serial_no = 1 %s""" % condition) for d in bin: serial_nos = frappe.db.sql("""select count(name) from `tabSerial No` where item_code=%s and warehouse=%s and docstatus < 2""", (d[0], d[1])) if serial_nos and flt(serial_nos[0][0]) != flt(d[2]): print d[0], d[1], d[2], serial_nos[0][0] sle = frappe.db.sql("""select valuation_rate, company from `tabStock Ledger Entry` where item_code = %s and warehouse = %s and ifnull(is_cancelled, 'No') = 'No' order by posting_date desc limit 1""", (d[0], d[1])) sle_dict = { 'doctype' : 'Stock Ledger Entry', 'item_code' : d[0], 'warehouse' : d[1], 'transaction_date' : nowdate(), 'posting_date' : posting_date, 'posting_time' : posting_time, 'voucher_type' : 'Stock Reconciliation (Manual)', 'voucher_no' : '', 'voucher_detail_no' : '', 'actual_qty' : flt(serial_nos[0][0]) - flt(d[2]), 'stock_uom' : d[3], 'incoming_rate' : sle and flt(serial_nos[0][0]) > flt(d[2]) and flt(sle[0][0]) or 0, 'company' : sle and cstr(sle[0][1]) or 0, 'is_cancelled' : 'No', 'batch_no' : '', 'serial_no' : '' } sle_doc = frappe.get_doc(sle_dict) sle_doc.flags.ignore_validate = True sle_doc.flags.ignore_links = True sle_doc.insert() args = sle_dict.copy() args.update({ "sle_id": sle_doc.name, "is_amended": 'No' }) update_bin(args) update_entries_after({ "item_code": d[0], "warehouse": d[1], "posting_date": posting_date, "posting_time": posting_time })
def update_planned_qty(self, pro_doc): from erpnext.stock.utils import update_bin update_bin({ "item_code": pro_doc.production_item, "warehouse": pro_doc.fg_warehouse, "posting_date": self.posting_date, "planned_qty": (self.docstatus==1 and -1 or 1 ) * flt(self.fg_completed_qty) })
def update_planned_qty(self, pro_doc): from erpnext.stock.utils import update_bin update_bin({ "item_code": pro_doc.production_item, "warehouse": pro_doc.fg_warehouse, "posting_date": self.posting_date, "planned_qty": (self.docstatus==1 and -1 or 1 ) * flt(self.fg_completed_qty) })
def update_planned_qty(self, qty): """update planned qty in bin""" args = { "item_code": self.production_item, "warehouse": self.fg_warehouse, "posting_date": nowdate(), "planned_qty": flt(qty) } from erpnext.stock.utils import update_bin update_bin(args)
def repost_stock(item_code, warehouse): repost_actual_qty(item_code, warehouse) if item_code and warehouse: update_bin(item_code, warehouse, { "reserved_qty": get_reserved_qty(item_code, warehouse), "indented_qty": get_indented_qty(item_code, warehouse), "ordered_qty": get_ordered_qty(item_code, warehouse), "planned_qty": get_planned_qty(item_code, warehouse) })
def update_planned_qty(self, qty): """update planned qty in bin""" args = { "item_code": self.production_item, "warehouse": self.fg_warehouse, "posting_date": nowdate(), "planned_qty": flt(qty) } from erpnext.stock.utils import update_bin update_bin(args)
def repost_stock(item_code, warehouse): repost_actual_qty(item_code, warehouse) if item_code and warehouse: update_bin( item_code, warehouse, { "reserved_qty": get_reserved_qty(item_code, warehouse), "indented_qty": get_indented_qty(item_code, warehouse), "ordered_qty": get_ordered_qty(item_code, warehouse), "planned_qty": get_planned_qty(item_code, warehouse) })
def update_bin(self, is_submit, is_stopped=0): from erpnext.stock.utils import update_bin pc_obj = frappe.get_doc("Purchase Common") for d in self.get("po_details"): # 1. Check if is_stock_item == 'Yes' if frappe.db.get_value("Item", d.item_code, "is_stock_item") == "Yes": # this happens when item is changed from non-stock to stock item if not d.warehouse: continue ind_qty, po_qty = 0, flt(d.qty) * flt(d.conversion_factor) if is_stopped: po_qty = ( flt(d.qty) > flt(d.received_qty) and flt(flt(flt(d.qty) - flt(d.received_qty)) * flt(d.conversion_factor)) or 0 ) # No updates in Material Request on Stop / Unstop if cstr(d.prevdoc_doctype) == "Material Request" and not is_stopped: # get qty and pending_qty of prevdoc curr_ref_qty = pc_obj.get_qty( d.doctype, "prevdoc_detail_docname", d.prevdoc_detail_docname, "Material Request Item", "Material Request - Purchase Order", self.name, ) max_qty, qty, curr_qty = flt(curr_ref_qty.split("~~~")[1]), flt(curr_ref_qty.split("~~~")[0]), 0 if flt(qty) + flt(po_qty) > flt(max_qty): curr_qty = flt(max_qty) - flt(qty) # special case as there is no restriction # for Material Request - Purchase Order curr_qty = curr_qty > 0 and curr_qty or 0 else: curr_qty = flt(po_qty) ind_qty = -flt(curr_qty) # Update ordered_qty and indented_qty in bin args = { "item_code": d.item_code, "warehouse": d.warehouse, "ordered_qty": (is_submit and 1 or -1) * flt(po_qty), "indented_qty": (is_submit and 1 or -1) * flt(ind_qty), "posting_date": self.transaction_date, } update_bin(args)
def update_stock_ledger(self, update_stock): from erpnext.stock.utils import update_bin for d in self.get_item_list(): if frappe.db.get_value("Item", d['item_code'], "is_stock_item") == "Yes": args = { "item_code": d['item_code'], "warehouse": d['reserved_warehouse'], "reserved_qty": flt(update_stock) * flt(d['reserved_qty']), "posting_date": self.transaction_date, "voucher_type": self.doctype, "voucher_no": self.name, "is_amended": self.amended_from and 'Yes' or 'No' } update_bin(args)
def update_stock_ledger(self, update_stock): from erpnext.stock.utils import update_bin for d in self.get_item_list(): if frappe.db.get_value("Item", d['item_code'], "is_stock_item") == "Yes": args = { "item_code": d['item_code'], "warehouse": d['reserved_warehouse'], "reserved_qty": flt(update_stock) * flt(d['reserved_qty']), "posting_date": self.transaction_date, "voucher_type": self.doctype, "voucher_no": self.name, "is_amended": self.amended_from and 'Yes' or 'No' } update_bin(args)
def update_reserved_qty(self, d): if d['reserved_qty'] < 0 : # Reduce reserved qty from reserved warehouse mentioned in so if not d["reserved_warehouse"]: frappe.throw(_("Reserved Warehouse is missing in Sales Order")) args = { "item_code": d['item_code'], "warehouse": d["reserved_warehouse"], "voucher_type": self.doctype, "voucher_no": self.name, "reserved_qty": (self.docstatus==1 and 1 or -1)*flt(d['reserved_qty']), "posting_date": self.posting_date, "is_amended": self.amended_from and 'Yes' or 'No' } update_bin(args)
def update_reserved_qty(self, d): if d['reserved_qty'] < 0 : # Reduce reserved qty from reserved warehouse mentioned in so if not d["reserved_warehouse"]: frappe.throw(_("Reserved Warehouse is missing in Sales Order")) args = { "item_code": d['item_code'], "warehouse": d["reserved_warehouse"], "voucher_type": self.doctype, "voucher_no": self.name, "reserved_qty": (self.docstatus==1 and 1 or -1)*flt(d['reserved_qty']), "posting_date": self.posting_date, "is_amended": self.amended_from and 'Yes' or 'No' } update_bin(args)
def update_bin(self, is_submit, is_stopped=0): from erpnext.stock.utils import update_bin pc_obj = frappe.get_doc('Purchase Common') for d in self.get('po_details'): #1. Check if is_stock_item == 'Yes' if frappe.db.get_value("Item", d.item_code, "is_stock_item") == "Yes": # this happens when item is changed from non-stock to stock item if not d.warehouse: continue ind_qty, po_qty = 0, flt(d.qty) * flt(d.conversion_factor) if is_stopped: po_qty = flt(d.qty) > flt(d.received_qty) and \ flt( flt(flt(d.qty) - flt(d.received_qty))*flt(d.conversion_factor)) or 0 # No updates in Material Request on Stop / Unstop if cstr(d.prevdoc_doctype ) == 'Material Request' and not is_stopped: # get qty and pending_qty of prevdoc curr_ref_qty = pc_obj.get_qty( d.doctype, 'prevdoc_detail_docname', d.prevdoc_detail_docname, 'Material Request Item', 'Material Request - Purchase Order', self.name) max_qty, qty, curr_qty = flt(curr_ref_qty.split('~~~')[1]), \ flt(curr_ref_qty.split('~~~')[0]), 0 if flt(qty) + flt(po_qty) > flt(max_qty): curr_qty = flt(max_qty) - flt(qty) # special case as there is no restriction # for Material Request - Purchase Order curr_qty = curr_qty > 0 and curr_qty or 0 else: curr_qty = flt(po_qty) ind_qty = -flt(curr_qty) # Update ordered_qty and indented_qty in bin args = { "item_code": d.item_code, "warehouse": d.warehouse, "ordered_qty": (is_submit and 1 or -1) * flt(po_qty), "indented_qty": (is_submit and 1 or -1) * flt(ind_qty), "posting_date": self.transaction_date } update_bin(args)
def update_bin(self, is_submit, is_stopped): """ Update Quantity Requested for Purchase in Bin for Material Request of type 'Purchase'""" from erpnext.stock.utils import update_bin for d in self.get('indent_details'): if frappe.db.get_value("Item", d.item_code, "is_stock_item") == "Yes": if not d.warehouse: frappe.throw(_("Warehouse required for stock Item {0}").format(d.item_code)) qty =flt(d.qty) if is_stopped: qty = (d.qty > d.ordered_qty) and flt(flt(d.qty) - flt(d.ordered_qty)) or 0 args = { "item_code": d.item_code, "warehouse": d.warehouse, "indented_qty": (is_submit and 1 or -1) * flt(qty), "posting_date": self.transaction_date } update_bin(args)
def update_bin(self, is_submit, is_stopped): """ Update Quantity Requested for Purchase in Bin for Material Request of type 'Purchase'""" from erpnext.stock.utils import update_bin for d in self.get('indent_details'): if frappe.db.get_value("Item", d.item_code, "is_stock_item") == "Yes": if not d.warehouse: frappe.throw(_("Warehouse required for stock Item {0}").format(d.item_code)) qty =flt(d.qty) if is_stopped: qty = (d.qty > d.ordered_qty) and flt(flt(d.qty) - flt(d.ordered_qty)) or 0 args = { "item_code": d.item_code, "warehouse": d.warehouse, "indented_qty": (is_submit and 1 or -1) * flt(qty), "posting_date": self.transaction_date } update_bin(args)
def make_sl_entries(sl_entries, is_amended=None): if sl_entries: from erpnext.stock.utils import update_bin cancel = True if sl_entries[0].get("is_cancelled") == "Yes" else False if cancel: set_as_cancel(sl_entries[0].get("voucher_no"), sl_entries[0].get("voucher_type")) for sle in sl_entries: sle_id = None if sle.get("is_cancelled") == "Yes": sle["actual_qty"] = -flt(sle["actual_qty"]) if sle.get("actual_qty"): sle_id = make_entry(sle) args = sle.copy() args.update({"sle_id": sle_id, "is_amended": is_amended}) update_bin(args) if cancel: delete_cancelled_entry(sl_entries[0].get("voucher_type"), sl_entries[0].get("voucher_no"))
def make_sl_entries(sl_entries, allow_negative_stock=False, via_landed_cost_voucher=False): if sl_entries: from erpnext.stock.utils import update_bin cancel = sl_entries[0].get("is_cancelled") if cancel: set_as_cancel(sl_entries[0].get('voucher_type'), sl_entries[0].get('voucher_no')) for sle in sl_entries: sle_id = None if via_landed_cost_voucher or cancel: sle['posting_date'] = now_datetime().strftime('%Y-%m-%d') sle['posting_time'] = now_datetime().strftime('%H:%M:%S.%f') if cancel: sle['actual_qty'] = -flt(sle.get('actual_qty')) if sle['actual_qty'] < 0 and not sle.get('outgoing_rate'): sle['outgoing_rate'] = get_incoming_outgoing_rate_for_cancel( sle.item_code, sle.voucher_type, sle.voucher_no, sle.voucher_detail_no) sle['incoming_rate'] = 0.0 if sle['actual_qty'] > 0 and not sle.get('incoming_rate'): sle['incoming_rate'] = get_incoming_outgoing_rate_for_cancel( sle.item_code, sle.voucher_type, sle.voucher_no, sle.voucher_detail_no) sle['outgoing_rate'] = 0.0 if sle.get("actual_qty") or sle.get( "voucher_type") == "Stock Reconciliation": sle_id = make_entry(sle, allow_negative_stock, via_landed_cost_voucher) args = sle.copy() args.update({"sle_id": sle_id}) update_bin(args, allow_negative_stock, via_landed_cost_voucher)
def update_ordered_qty(self): stock_items = self.get_stock_items() for d in self.get("purchase_receipt_details"): if d.item_code in stock_items and d.warehouse \ and cstr(d.prevdoc_doctype) == 'Purchase Order': already_received_qty = self.get_already_received_qty(d.prevdoc_docname, d.prevdoc_detail_docname) po_qty, ordered_warehouse = self.get_po_qty_and_warehouse(d.prevdoc_detail_docname) if not ordered_warehouse: frappe.throw(_("Warehouse is missing in Purchase Order")) if already_received_qty + d.qty > po_qty: ordered_qty = - (po_qty - already_received_qty) * flt(d.conversion_factor) else: ordered_qty = - flt(d.qty) * flt(d.conversion_factor) update_bin({ "item_code": d.item_code, "warehouse": ordered_warehouse, "posting_date": self.posting_date, "ordered_qty": flt(ordered_qty) if self.docstatus==1 else -flt(ordered_qty) })
def set_stock_balance_as_per_serial_no(item_code=None, posting_date=None, posting_time=None, fiscal_year=None): if not posting_date: posting_date = nowdate() if not posting_time: posting_time = nowtime() condition = " and item.name='%s'" % item_code.replace( "'", "'") if item_code else "" bin = frappe.db.sql( """select bin.item_code, bin.warehouse, bin.actual_qty, item.stock_uom from `tabBin` bin, tabItem item where bin.item_code = item.name and item.has_serial_no = 1 %s""" % condition) for d in bin: serial_nos = frappe.db.sql( """select count(name) from `tabSerial No` where item_code=%s and warehouse=%s and docstatus < 2""", (d[0], d[1]), ) sle = frappe.db.sql( """select valuation_rate, company from `tabStock Ledger Entry` where item_code = %s and warehouse = %s and is_cancelled = 0 order by posting_date desc limit 1""", (d[0], d[1]), ) sle_dict = { "doctype": "Stock Ledger Entry", "item_code": d[0], "warehouse": d[1], "transaction_date": nowdate(), "posting_date": posting_date, "posting_time": posting_time, "voucher_type": "Stock Reconciliation (Manual)", "voucher_no": "", "voucher_detail_no": "", "actual_qty": flt(serial_nos[0][0]) - flt(d[2]), "stock_uom": d[3], "incoming_rate": sle and flt(serial_nos[0][0]) > flt(d[2]) and flt(sle[0][0]) or 0, "company": sle and cstr(sle[0][1]) or 0, "batch_no": "", "serial_no": "", } sle_doc = frappe.get_doc(sle_dict) sle_doc.flags.ignore_validate = True sle_doc.flags.ignore_links = True sle_doc.insert() args = sle_dict.copy() args.update({"sle_id": sle_doc.name}) update_bin(args) create_repost_item_valuation_entry({ "item_code": d[0], "warehouse": d[1], "posting_date": posting_date, "posting_time": posting_time, })
def set_stock_balance_as_per_serial_no(item_code=None, posting_date=None, posting_time=None, fiscal_year=None): if not posting_date: posting_date = nowdate() if not posting_time: posting_time = nowtime() if not fiscal_year: fiscal_year = get_fiscal_year(posting_date)[0] condition = " and item.name='%s'" % item_code.replace("'", "'") if item_code else "" bin = frappe.db.sql( """select bin.item_code, bin.warehouse, bin.actual_qty, item.stock_uom from `tabBin` bin, tabItem item where bin.item_code = item.name and item.has_serial_no = 'Yes' %s""" % condition ) for d in bin: serial_nos = frappe.db.sql( """select count(name) from `tabSerial No` where item_code=%s and warehouse=%s and status = 'Available' and docstatus < 2""", (d[0], d[1]), ) if serial_nos and flt(serial_nos[0][0]) != flt(d[2]): print d[0], d[1], d[2], serial_nos[0][0] sle = frappe.db.sql( """select valuation_rate, company from `tabStock Ledger Entry` where item_code = %s and warehouse = %s and ifnull(is_cancelled, 'No') = 'No' order by posting_date desc limit 1""", (d[0], d[1]), ) sle_dict = { "doctype": "Stock Ledger Entry", "item_code": d[0], "warehouse": d[1], "transaction_date": nowdate(), "posting_date": posting_date, "posting_time": posting_time, "voucher_type": "Stock Reconciliation (Manual)", "voucher_no": "", "voucher_detail_no": "", "actual_qty": flt(serial_nos[0][0]) - flt(d[2]), "stock_uom": d[3], "incoming_rate": sle and flt(serial_nos[0][0]) > flt(d[2]) and flt(sle[0][0]) or 0, "company": sle and cstr(sle[0][1]) or 0, "fiscal_year": fiscal_year, "is_cancelled": "No", "batch_no": "", "serial_no": "", } sle_doc = frappe.get_doc(sle_dict) sle_doc.insert() args = sle_dict.copy() args.update({"sle_id": sle_doc.name, "is_amended": "No"}) update_bin(args) update_entries_after( {"item_code": d[0], "warehouse": d[1], "posting_date": posting_date, "posting_time": posting_time} )