Ejemplo n.º 1
0
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'))
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
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'))
Ejemplo n.º 4
0
    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)
                })
Ejemplo n.º 5
0
	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'))
Ejemplo n.º 6
0
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,
			})
Ejemplo n.º 7
0
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,
        })
Ejemplo n.º 8
0
	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'))
Ejemplo n.º 9
0
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
		})
Ejemplo n.º 10
0
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)
		})
Ejemplo n.º 12
0
	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)
		})
Ejemplo n.º 13
0
	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)
Ejemplo n.º 14
0
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)
		})
Ejemplo n.º 15
0
 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)
Ejemplo n.º 16
0
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)
            })
Ejemplo n.º 17
0
    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)
Ejemplo n.º 18
0
	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)
Ejemplo n.º 19
0
	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)
Ejemplo n.º 20
0
	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)
Ejemplo n.º 21
0
	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)
Ejemplo n.º 22
0
    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)
Ejemplo n.º 23
0
	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)
Ejemplo n.º 24
0
	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)
Ejemplo n.º 25
0
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"))
Ejemplo n.º 26
0
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)
Ejemplo n.º 27
0
	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)
				})
Ejemplo n.º 28
0
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,
        })
Ejemplo n.º 29
0
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}
        )