mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-29 18:04:46 +00:00
incoming rate for sales return as per delivery note outgoing rate
This commit is contained in:
@@ -226,7 +226,8 @@ cur_frm.cscript.s_warehouse = function(doc, cdt, cdn) {
|
|||||||
'warehouse' : cstr(d.s_warehouse) || cstr(d.t_warehouse),
|
'warehouse' : cstr(d.s_warehouse) || cstr(d.t_warehouse),
|
||||||
'transfer_qty' : d.transfer_qty,
|
'transfer_qty' : d.transfer_qty,
|
||||||
'serial_no' : d.serial_no,
|
'serial_no' : d.serial_no,
|
||||||
'bom_no' : d.bom_no
|
'bom_no' : d.bom_no,
|
||||||
|
'qty' : d.s_warehouse ? -1* d.qty : d.qty
|
||||||
}
|
}
|
||||||
get_server_fields('get_warehouse_details', JSON.stringify(args),
|
get_server_fields('get_warehouse_details', JSON.stringify(args),
|
||||||
'mtn_details', doc, cdt, cdn, 1);
|
'mtn_details', doc, cdt, cdn, 1);
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ from webnotes.model.code import get_obj
|
|||||||
from webnotes import msgprint, _
|
from webnotes import msgprint, _
|
||||||
from stock.utils import get_incoming_rate
|
from stock.utils import get_incoming_rate
|
||||||
from stock.stock_ledger import get_previous_sle
|
from stock.stock_ledger import get_previous_sle
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
sql = webnotes.conn.sql
|
sql = webnotes.conn.sql
|
||||||
|
|
||||||
@@ -157,24 +159,47 @@ class DocType(TransactionBase):
|
|||||||
def get_stock_and_rate(self):
|
def get_stock_and_rate(self):
|
||||||
"""get stock and incoming rate on posting date"""
|
"""get stock and incoming rate on posting date"""
|
||||||
for d in getlist(self.doclist, 'mtn_details'):
|
for d in getlist(self.doclist, 'mtn_details'):
|
||||||
args = {
|
args = webnotes._dict({
|
||||||
"item_code": d.item_code,
|
"item_code": d.item_code,
|
||||||
"warehouse": d.s_warehouse or d.t_warehouse,
|
"warehouse": d.s_warehouse or d.t_warehouse,
|
||||||
"posting_date": self.doc.posting_date,
|
"posting_date": self.doc.posting_date,
|
||||||
"posting_time": self.doc.posting_time,
|
"posting_time": self.doc.posting_time,
|
||||||
"qty": d.transfer_qty,
|
"qty": d.s_warehouse and -1*d.transfer_qty or d.transfer_qty,
|
||||||
"serial_no": d.serial_no,
|
"serial_no": d.serial_no,
|
||||||
"bom_no": d.bom_no
|
"bom_no": d.bom_no,
|
||||||
}
|
})
|
||||||
# get actual stock at source warehouse
|
# get actual stock at source warehouse
|
||||||
d.actual_qty = get_previous_sle(args).get("qty_after_transaction") or 0
|
d.actual_qty = get_previous_sle(args).get("qty_after_transaction") or 0
|
||||||
|
|
||||||
# get incoming rate
|
# get incoming rate
|
||||||
if not flt(d.incoming_rate):
|
if not flt(d.incoming_rate) or self.doc.purpose == "Sales Return":
|
||||||
d.incoming_rate = get_incoming_rate(args)
|
d.incoming_rate = self.get_incoming_rate(args)
|
||||||
|
|
||||||
d.amount = flt(d.qty) * flt(d.incoming_rate)
|
d.amount = flt(d.qty) * flt(d.incoming_rate)
|
||||||
|
|
||||||
|
def get_incoming_rate(self, args):
|
||||||
|
if self.doc.purpose == "Sales Return" and \
|
||||||
|
(self.doc.delivery_note_no or self.doc.sales_invoice_no):
|
||||||
|
sle = webnotes.conn.sql("""select name, posting_date, posting_time,
|
||||||
|
actual_qty, stock_value from `tabStock Ledger Entry`
|
||||||
|
where voucher_type = %s and voucher_no = %s and
|
||||||
|
item_code = %s and ifnull(is_cancelled, 'No') = 'No' limit 1""",
|
||||||
|
((self.doc.delivery_note_no and "Delivery Note" or "Sales Invoice"),
|
||||||
|
self.doc.delivery_note_no or self.doc.sales_invoice_no, args.item_code), as_dict=1)
|
||||||
|
if sle:
|
||||||
|
args.update({
|
||||||
|
"posting_date": sle[0].posting_date,
|
||||||
|
"posting_time": sle[0].posting_time,
|
||||||
|
"sle": sle[0].name
|
||||||
|
})
|
||||||
|
previous_sle = get_previous_sle(args)
|
||||||
|
incoming_rate = (flt(sle[0].stock_value) - flt(previous_sle.get("stock_value"))) / \
|
||||||
|
flt(sle[0].actual_qty)
|
||||||
|
else:
|
||||||
|
incoming_rate = get_incoming_rate(args)
|
||||||
|
|
||||||
|
return incoming_rate
|
||||||
|
|
||||||
def validate_incoming_rate(self):
|
def validate_incoming_rate(self):
|
||||||
for d in getlist(self.doclist, 'mtn_details'):
|
for d in getlist(self.doclist, 'mtn_details'):
|
||||||
if not flt(d.incoming_rate) and d.t_warehouse:
|
if not flt(d.incoming_rate) and d.t_warehouse:
|
||||||
@@ -264,8 +289,7 @@ class DocType(TransactionBase):
|
|||||||
pro_obj.doc.save()
|
pro_obj.doc.save()
|
||||||
|
|
||||||
def get_item_details(self, arg):
|
def get_item_details(self, arg):
|
||||||
import json
|
arg = json.loads(arg)
|
||||||
arg, actual_qty, in_rate = json.loads(arg), 0, 0
|
|
||||||
|
|
||||||
item = sql("""select stock_uom, description, item_name from `tabItem`
|
item = sql("""select stock_uom, description, item_name from `tabItem`
|
||||||
where name = %s and (ifnull(end_of_life,'')='' or end_of_life ='0000-00-00'
|
where name = %s and (ifnull(end_of_life,'')='' or end_of_life ='0000-00-00'
|
||||||
@@ -305,16 +329,16 @@ class DocType(TransactionBase):
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
def get_warehouse_details(self, args):
|
def get_warehouse_details(self, args):
|
||||||
import json
|
args = json.loads(args)
|
||||||
args, actual_qty, in_rate = json.loads(args), 0, 0
|
|
||||||
args.update({
|
args.update({
|
||||||
"posting_date": self.doc.posting_date,
|
"posting_date": self.doc.posting_date,
|
||||||
"posting_time": self.doc.posting_time
|
"posting_time": self.doc.posting_time,
|
||||||
})
|
})
|
||||||
|
args = webnotes._dict(args)
|
||||||
|
|
||||||
ret = {
|
ret = {
|
||||||
"actual_qty" : get_previous_sle(args).get("qty_after_transaction") or 0,
|
"actual_qty" : get_previous_sle(args).get("qty_after_transaction") or 0,
|
||||||
"incoming_rate" : get_incoming_rate(args)
|
"incoming_rate" : self.get_incoming_rate(args)
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
{
|
{
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"creation": "2013-01-14 15:14:40",
|
"creation": "2013-01-15 12:28:57",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"modified": "2013-01-15 12:25:13"
|
"modified": "2013-01-16 13:59:28"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_attach": 0,
|
"allow_attach": 0,
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
"search_fields": "posting_date",
|
"search_fields": "posting_date",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
|
"read_only_onload": 0,
|
||||||
"autoname": "SR/.######",
|
"autoname": "SR/.######",
|
||||||
"description": "This tool helps you to update or fix the quantity and valuation of stock in the system. It is typically used to synchronise the system values and what actually exists in your warehouses.",
|
"description": "This tool helps you to update or fix the quantity and valuation of stock in the system. It is typically used to synchronise the system values and what actually exists in your warehouses.",
|
||||||
"allow_email": 1,
|
"allow_email": 1,
|
||||||
@@ -33,7 +34,7 @@
|
|||||||
"read": 1,
|
"read": 1,
|
||||||
"cancel": 1,
|
"cancel": 1,
|
||||||
"name": "__common__",
|
"name": "__common__",
|
||||||
"amend": 0,
|
"amend": 1,
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"doctype": "DocPerm",
|
"doctype": "DocPerm",
|
||||||
"submit": 1,
|
"submit": 1,
|
||||||
|
|||||||
@@ -78,12 +78,11 @@ def get_incoming_rate(args):
|
|||||||
valuation_method = get_valuation_method(args.get("item_code"))
|
valuation_method = get_valuation_method(args.get("item_code"))
|
||||||
previous_sle = get_previous_sle(args)
|
previous_sle = get_previous_sle(args)
|
||||||
if valuation_method == 'FIFO':
|
if valuation_method == 'FIFO':
|
||||||
# get rate based on the last item value?
|
if not previous_sle:
|
||||||
if args.get("qty"):
|
return 0.0
|
||||||
if not previous_sle:
|
previous_stock_queue = json.loads(previous_sle.get('stock_queue', '[]'))
|
||||||
return 0.0
|
in_rate = previous_stock_queue and \
|
||||||
stock_queue = json.loads(previous_sle.get('stock_queue', '[]'))
|
get_fifo_rate(previous_stock_queue, args.get("qty")) or 0
|
||||||
in_rate = stock_queue and get_fifo_rate(stock_queue) or 0
|
|
||||||
elif valuation_method == 'Moving Average':
|
elif valuation_method == 'Moving Average':
|
||||||
in_rate = previous_sle.get('valuation_rate') or 0
|
in_rate = previous_sle.get('valuation_rate') or 0
|
||||||
return in_rate
|
return in_rate
|
||||||
@@ -104,13 +103,29 @@ def get_valuation_method(item_code):
|
|||||||
val_method = get_defaults().get('valuation_method', 'FIFO')
|
val_method = get_defaults().get('valuation_method', 'FIFO')
|
||||||
return val_method
|
return val_method
|
||||||
|
|
||||||
def get_fifo_rate(stock_queue):
|
def get_fifo_rate(previous_stock_queue, qty):
|
||||||
"""get FIFO (average) Rate from Stack"""
|
"""get FIFO (average) Rate from Queue"""
|
||||||
if not stock_queue:
|
if qty >= 0:
|
||||||
return 0.0
|
total = sum(f[0] for f in previous_stock_queue)
|
||||||
|
return total and sum(f[0] * f[1] for f in previous_stock_queue) / flt(total) or 0.0
|
||||||
|
else:
|
||||||
|
outgoing_cost = 0
|
||||||
|
qty_to_pop = abs(qty)
|
||||||
|
while qty_to_pop:
|
||||||
|
batch = previous_stock_queue[0]
|
||||||
|
if 0 < batch[0] <= qty_to_pop:
|
||||||
|
# if batch qty > 0
|
||||||
|
# not enough or exactly same qty in current batch, clear batch
|
||||||
|
outgoing_cost += flt(batch[0]) * flt(batch[1])
|
||||||
|
qty_to_pop -= batch[0]
|
||||||
|
previous_stock_queue.pop(0)
|
||||||
|
else:
|
||||||
|
# all from current batch
|
||||||
|
outgoing_cost += flt(qty_to_pop) * flt(batch[1])
|
||||||
|
batch[0] -= qty_to_pop
|
||||||
|
qty_to_pop = 0
|
||||||
|
|
||||||
total = sum(f[0] for f in stock_queue)
|
return outgoing_cost / abs(qty)
|
||||||
return total and sum(f[0] * f[1] for f in stock_queue) / flt(total) or 0.0
|
|
||||||
|
|
||||||
def get_valid_serial_nos(sr_nos, qty=0, item_code=''):
|
def get_valid_serial_nos(sr_nos, qty=0, item_code=''):
|
||||||
"""split serial nos, validate and return list of valid serial nos"""
|
"""split serial nos, validate and return list of valid serial nos"""
|
||||||
|
|||||||
Reference in New Issue
Block a user