Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delivery to target warehouse #4040

Merged
merged 6 commits into from
Oct 14, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion erpnext/accounts/doctype/sales_invoice/sales_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ def update_current_stock(self):
def update_packing_list(self):
if cint(self.update_stock) == 1:
from erpnext.stock.doctype.packed_item.packed_item import make_packing_list
make_packing_list(self, 'items')
make_packing_list(self)
else:
self.set('packed_items', [])

Expand Down
26 changes: 10 additions & 16 deletions erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry, get_qty_after_transaction
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
from erpnext.exceptions import InvalidAccountCurrency, InvalidCurrency
from erpnext.stock.doctype.serial_no.serial_no import SerialNoWarehouseError
from frappe.model.naming import make_autoname

class TestSalesInvoice(unittest.TestCase):
def make(self):
Expand Down Expand Up @@ -688,7 +690,6 @@ def test_serialized(self):
si.insert()
si.submit()

self.assertEquals(frappe.db.get_value("Serial No", serial_nos[0], "status"), "Delivered")
self.assertFalse(frappe.db.get_value("Serial No", serial_nos[0], "warehouse"))
self.assertEquals(frappe.db.get_value("Serial No", serial_nos[0],
"delivery_document_no"), si.name)
Expand All @@ -702,33 +703,26 @@ def test_serialized_cancel(self):

serial_nos = get_serial_nos(si.get("items")[0].serial_no)

self.assertEquals(frappe.db.get_value("Serial No", serial_nos[0], "status"), "Available")
self.assertEquals(frappe.db.get_value("Serial No", serial_nos[0], "warehouse"), "_Test Warehouse - _TC")
self.assertFalse(frappe.db.get_value("Serial No", serial_nos[0],
"delivery_document_no"))

def test_serialize_status(self):
from erpnext.stock.doctype.serial_no.serial_no import SerialNoStatusError, get_serial_nos, SerialNoDuplicateError
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_serialized_item

se = make_serialized_item()
serial_nos = get_serial_nos(se.get("items")[0].serial_no)

sr = frappe.get_doc("Serial No", serial_nos[0])
sr.status = "Not Available"
sr.save()
serial_no = frappe.get_doc({
"doctype": "Serial No",
"item_code": "_Test Serialized Item With Series",
"serial_no": make_autoname("SR", "Serial No")
})
serial_no.save()

si = frappe.copy_doc(test_records[0])
si.update_stock = 1
si.get("items")[0].item_code = "_Test Serialized Item With Series"
si.get("items")[0].qty = 1
si.get("items")[0].serial_no = serial_nos[0]
si.get("items")[0].serial_no = serial_no.name
si.insert()

self.assertRaises(SerialNoStatusError, si.submit)

# hack! because stock ledger entires are already inserted and are not rolled back!
self.assertRaises(SerialNoDuplicateError, si.cancel)
self.assertRaises(SerialNoWarehouseError, si.submit)

def test_invoice_due_date_against_customers_credit_days(self):
# set customer's credit days
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,29 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "target_warehouse",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Target Warehouse",
"no_copy": 0,
"options": "Warehouse",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
Expand Down Expand Up @@ -1259,7 +1282,7 @@
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"modified": "2015-08-20 17:18:52.752064",
"modified": "2015-09-20 21:26:46.279615",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Item",
Expand Down
2 changes: 2 additions & 0 deletions erpnext/change_log/current/delivery_to_target_warehouse.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Delivery to Target Warehouse: Now you can deliver items to customer's warehouse or rented warehouse. Sponsored by: **[Startrack](http://www.gps.gt/)**
- Serial No **Status** deprecated
6 changes: 4 additions & 2 deletions erpnext/controllers/selling_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,8 @@ def get_item_list(self):
'uom': p.uom,
'batch_no': cstr(p.batch_no).strip(),
'serial_no': cstr(p.serial_no).strip(),
'name': d.name
'name': d.name,
'target_warehouse': p.target_warehouse
}))
else:
il.append(frappe._dict({
Expand All @@ -184,7 +185,8 @@ def get_item_list(self):
'stock_uom': d.stock_uom,
'batch_no': cstr(d.get("batch_no")).strip(),
'serial_no': cstr(d.get("serial_no")).strip(),
'name': d.name
'name': d.name,
'target_warehouse': d.target_warehouse
}))
return il

Expand Down
69 changes: 53 additions & 16 deletions erpnext/controllers/stock_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from frappe import msgprint, _
import frappe.defaults
from erpnext.accounts.general_ledger import make_gl_entries, delete_gl_entries, process_gl_map
from erpnext.stock.utils import get_incoming_rate

from erpnext.controllers.accounts_controller import AccountsController

Expand Down Expand Up @@ -184,7 +185,7 @@ def get_sl_entries(self, d, args):
"voucher_no": self.name,
"voucher_detail_no": d.name,
"actual_qty": (self.docstatus==1 and 1 or -1)*flt(d.get("stock_qty")),
"stock_uom": d.get("stock_uom"),
"stock_uom": frappe.db.get_value("Item", args.get("item_code") or d.get("item_code"), "stock_uom"),
"incoming_rate": 0,
"company": self.company,
"fiscal_year": self.fiscal_year,
Expand Down Expand Up @@ -217,13 +218,14 @@ def get_serialized_items(self):

return serialized_items

def get_incoming_rate_for_sales_return(self, item_code, against_document):
def get_incoming_rate_for_sales_return(self, item_code, warehouse, against_document):
incoming_rate = 0.0
if against_document and item_code:
incoming_rate = frappe.db.sql("""select abs(ifnull(stock_value_difference, 0) / actual_qty)
from `tabStock Ledger Entry`
where voucher_type = %s and voucher_no = %s and item_code = %s limit 1""",
(self.doctype, against_document, item_code))
where voucher_type = %s and voucher_no = %s
and item_code = %s and warehouse=%s limit 1""",
(self.doctype, against_document, item_code, warehouse))
incoming_rate = incoming_rate[0][0] if incoming_rate else 0.0

return incoming_rate
Expand Down Expand Up @@ -252,19 +254,54 @@ def update_stock_ledger(self):

sl_entries = []
for d in self.get_item_list():
if frappe.db.get_value("Item", d.item_code, "is_stock_item") == 1 \
and d.warehouse and flt(d['qty']):

incoming_rate = 0
if frappe.db.get_value("Item", d.item_code, "is_stock_item") == 1 and flt(d.qty):
return_rate = 0
if cint(self.is_return) and self.return_against and self.docstatus==1:
incoming_rate = self.get_incoming_rate_for_sales_return(d.item_code, self.return_against)

sl_entries.append(self.get_sl_entries(d, {
"actual_qty": -1*flt(d['qty']),
"stock_uom": frappe.db.get_value("Item", d.item_code, "stock_uom"),
"incoming_rate": incoming_rate
}))

return_rate = self.get_incoming_rate_for_sales_return(d.item_code,
d.warehouse, self.return_against)

# On cancellation or if return entry submission, make stock ledger entry for
# target warehouse first, to update serial no values properly

if d.warehouse and ((not cint(self.is_return) and self.docstatus==1)
or (cint(self.is_return) and self.docstatus==2)):
sl_entries.append(self.get_sl_entries(d, {
"actual_qty": -1*flt(d.qty),
"incoming_rate": return_rate
}))

if d.target_warehouse:
target_warehouse_sle = self.get_sl_entries(d, {
"actual_qty": flt(d.qty),
"warehouse": d.target_warehouse
})

if self.docstatus == 1:
if not cint(self.is_return):
args = frappe._dict({
"item_code": d.item_code,
"warehouse": d.warehouse,
"posting_date": self.posting_date,
"posting_time": self.posting_time,
"qty": -1*flt(d.qty),
"serial_no": d.serial_no
})
target_warehouse_sle.update({
"incoming_rate": get_incoming_rate(args)
})
else:
target_warehouse_sle.update({
"outgoing_rate": return_rate
})
sl_entries.append(target_warehouse_sle)

if d.warehouse and ((not cint(self.is_return) and self.docstatus==2)
or (cint(self.is_return) and self.docstatus==1)):
sl_entries.append(self.get_sl_entries(d, {
"actual_qty": -1*flt(d.qty),
"incoming_rate": return_rate
}))

self.make_sl_entries(sl_entries)

def update_gl_entries_after(posting_date, posting_time, for_warehouses=None, for_items=None,
Expand Down
2 changes: 1 addition & 1 deletion erpnext/selling/doctype/sales_order/sales_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def validate(self):
self.validate_warehouse()

from erpnext.stock.doctype.packed_item.packed_item import make_packing_list
make_packing_list(self,'items')
make_packing_list(self)

self.validate_with_previous_doc()
self.set_status()
Expand Down
25 changes: 24 additions & 1 deletion erpnext/selling/doctype/sales_order_item/sales_order_item.json
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,29 @@
"unique": 0,
"width": "150px"
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "target_warehouse",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Target Warehouse",
"no_copy": 0,
"options": "Warehouse",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
Expand Down Expand Up @@ -1072,7 +1095,7 @@
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"modified": "2015-08-27 02:29:20.603580",
"modified": "2015-09-20 21:26:22.732109",
"modified_by": "Administrator",
"module": "Selling",
"name": "Sales Order Item",
Expand Down
2 changes: 1 addition & 1 deletion erpnext/stock/doctype/delivery_note/delivery_note.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def validate(self):
self.validate_with_previous_doc()

from erpnext.stock.doctype.packed_item.packed_item import make_packing_list
make_packing_list(self, 'items')
make_packing_list(self)

self.update_current_stock()

Expand Down
Loading