diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index b88623b3ad..005abe646d 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -289,7 +289,7 @@ def get_credit_days(party_type, party, company):
credit_days_based_on, credit_days = \
frappe.db.get_value("Supplier Type", supplier_type, ["credit_days_based_on", "credit_days"])
- if not (credit_days_based_on and credit_days):
+ if not credit_days_based_on:
credit_days_based_on, credit_days = \
frappe.db.get_value("Company", company, ["credit_days_based_on", "credit_days"])
diff --git a/erpnext/controllers/tests/test_recurring_document.py b/erpnext/controllers/tests/test_recurring_document.py
index d47c5c7701..e218fa6c9b 100644
--- a/erpnext/controllers/tests/test_recurring_document.py
+++ b/erpnext/controllers/tests/test_recurring_document.py
@@ -27,7 +27,8 @@ def test_recurring_document(obj, test_records):
base_doc.set(date_field, today)
if base_doc.doctype == "Sales Order":
- base_doc.set("delivery_date", add_days(today, 15))
+ for d in base_doc.get("items"):
+ d.set("delivery_date", add_days(today, 15))
# monthly
doc1 = frappe.copy_doc(base_doc)
diff --git a/erpnext/demo/user/sales.py b/erpnext/demo/user/sales.py
index ddd36efc36..666e201716 100644
--- a/erpnext/demo/user/sales.py
+++ b/erpnext/demo/user/sales.py
@@ -118,7 +118,8 @@ def make_sales_order():
from erpnext.selling.doctype.quotation.quotation import make_sales_order
so = frappe.get_doc(make_sales_order(q))
so.transaction_date = frappe.flags.current_date
- so.delivery_date = frappe.utils.add_days(frappe.flags.current_date, 10)
+ for d in so.get("items"):
+ d.delivery_date = frappe.utils.add_days(frappe.flags.current_date, 10)
so.insert()
frappe.db.commit()
so.submit()
diff --git a/erpnext/docs/assets/img/selling/make-so.gif b/erpnext/docs/assets/img/selling/make-so.gif
index 5edd19b887..0e568a8d3d 100644
Binary files a/erpnext/docs/assets/img/selling/make-so.gif and b/erpnext/docs/assets/img/selling/make-so.gif differ
diff --git a/erpnext/docs/user/manual/en/selling/sales-order.md b/erpnext/docs/user/manual/en/selling/sales-order.md
index 99b9a85c25..b103038036 100644
--- a/erpnext/docs/user/manual/en/selling/sales-order.md
+++ b/erpnext/docs/user/manual/en/selling/sales-order.md
@@ -31,7 +31,7 @@ Most of the information in your Sales Order is the same as the Quotation.
There are a few amongst other things that a Sales Order will ask you to
update.
- * Expected date of delivery.
+ * Enter delivery date agaist each item. If there are multiple items and if you enter delivery date in the first row, the date will be copied to other rows as well where it is blank.
* Customer Purchase Order number: If your customer has sent you a Purchase Order, you can update its number for future reference (in billing).
### Packing List
@@ -89,9 +89,9 @@ ERPNext will automatically create new Order and mail a notification to the Email
Once you “Submit” your Sales Order, you can now trigger different aspects of
your organization:
- * To begin purchase click on “Make Purchase Request”
- * To make a shipment entry click on “Make Delivery Note”
- * To bill, make “Make Sales Invoice”
+ * To begin purchase click on Make -> Purchase Request
+ * To make a shipment entry click on Make -> Delivery Note. You can also make Delivery Note for selected items based on delivery date.
+ * To bill, make Make -> Sales Invoice
* To stop further process on this Sales Order, click on “Stop”
### Submission
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.js b/erpnext/manufacturing/doctype/production_order/production_order.js
index 657819a0b0..c61eec620a 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.js
+++ b/erpnext/manufacturing/doctype/production_order/production_order.js
@@ -77,7 +77,6 @@ frappe.ui.form.on("Production Order", {
if (!frm.doc.status)
frm.doc.status = 'Draft';
- frm.add_fetch("sales_order", "delivery_date", "expected_delivery_date");
frm.add_fetch("sales_order", "project", "project");
if(frm.doc.__islocal) {
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py
index 040a5592f9..511f6de703 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/production_order.py
@@ -50,8 +50,12 @@ class ProductionOrder(Document):
def validate_sales_order(self):
if self.sales_order:
- so = frappe.db.sql("""select name, delivery_date, project from `tabSales Order`
- where name=%s and docstatus = 1""", self.sales_order, as_dict=1)
+ so = frappe.db.sql("""
+ select so.name, so_item.delivery_date, so.project
+ from `tabSales Order` so, `tabSales Order Item` so_item
+ where so.name=%s and so.name=so_item.parent
+ and so.docstatus = 1 and so_item.item_code=%s
+ """, (self.sales_order, self.production_item), as_dict=1)
if len(so):
if not self.expected_delivery_date:
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 5b45cb4bd5..6119f3de86 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -421,4 +421,5 @@ erpnext.patches.v8_1.removed_report_support_hours
erpnext.patches.v8_1.add_indexes_in_transaction_doctypes
erpnext.patches.v8_3.set_restrict_to_domain_for_module_def
erpnext.patches.v8_1.update_expense_claim_status
-erpnext.patches.v8_3.update_company_total_sales
\ No newline at end of file
+erpnext.patches.v8_3.update_company_total_sales
+erpnext.patches.v8_1.set_delivery_date_in_so_item
\ No newline at end of file
diff --git a/erpnext/patches/v8_1/set_delivery_date_in_so_item.py b/erpnext/patches/v8_1/set_delivery_date_in_so_item.py
new file mode 100644
index 0000000000..6840424774
--- /dev/null
+++ b/erpnext/patches/v8_1/set_delivery_date_in_so_item.py
@@ -0,0 +1,13 @@
+import frappe
+
+def execute():
+ frappe.reload_doctype("Sales Order")
+ frappe.reload_doctype("Sales Order Item")
+
+ frappe.db.sql("""update `tabSales Order` set final_delivery_date = delivery_date where docstatus=1""")
+
+ frappe.db.sql("""
+ update `tabSales Order` so, `tabSales Order Item` so_item
+ set so_item.delivery_date = so.delivery_date
+ where so.name = so_item.parent
+ """)
\ No newline at end of file
diff --git a/erpnext/selling/doctype/quotation/test_quotation.py b/erpnext/selling/doctype/quotation/test_quotation.py
index 640c026c66..7fb40748f0 100644
--- a/erpnext/selling/doctype/quotation/test_quotation.py
+++ b/erpnext/selling/doctype/quotation/test_quotation.py
@@ -27,7 +27,8 @@ class TestQuotation(unittest.TestCase):
self.assertEquals(sales_order.get("items")[0].prevdoc_docname, quotation.name)
self.assertEquals(sales_order.customer, "_Test Customer")
- sales_order.delivery_date = "2014-01-01"
+ for d in sales_order.get("items"):
+ d.delivery_date = "2014-01-01"
sales_order.naming_series = "_T-Quotation-"
sales_order.transaction_date = "2013-05-12"
sales_order.insert()
@@ -51,9 +52,11 @@ class TestQuotation(unittest.TestCase):
quotation.submit()
sales_order = make_sales_order(quotation.name)
- sales_order.delivery_date = "2016-01-02"
sales_order.naming_series = "_T-Quotation-"
sales_order.transaction_date = "2016-01-01"
+ for d in sales_order.get("items"):
+ d.delivery_date = "2016-01-02"
+
sales_order.insert()
self.assertEquals(quotation.get("items")[0].rate, rate_with_margin)
@@ -86,4 +89,4 @@ def get_quotation_dict(customer=None, item_code=None):
'rate': 100
}
]
- }
\ No newline at end of file
+ }
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index 457b6aad84..2e01a08359 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -33,7 +33,13 @@ frappe.ui.form.on("Sales Order", {
function(doc) { return (doc.stock_qty<=doc.delivered_qty) ? "green" : "orange" })
erpnext.queries.setup_warehouse_query(frm);
- }
+ },
+});
+
+frappe.ui.form.on("Sales Order Item", {
+ delivery_date: function(frm, cdt, cdn) {
+ erpnext.utils.copy_value_in_all_row(frm.doc, cdt, cdn, "items", "delivery_date");
+ }
});
erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend({
@@ -77,7 +83,7 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
// delivery note
if(flt(doc.per_delivered, 2) < 100 && ["Sales", "Shopping Cart"].indexOf(doc.order_type)!==-1 && allow_delivery) {
this.frm.add_custom_button(__('Delivery'),
- function() { me.make_delivery_note() }, __("Make"));
+ function() { me.make_delivery_note_based_on_delivery_note(); }, __("Make"));
this.frm.add_custom_button(__('Production Order'),
function() { me.make_production_order() }, __("Make"));
@@ -235,7 +241,7 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
},
order_type: function() {
- this.frm.toggle_reqd("delivery_date", this.frm.doc.order_type == "Sales");
+ this.frm.fields_dict.items.grid.toggle_reqd("delivery_date", this.frm.doc.order_type == "Sales");
},
tc_name: function() {
@@ -249,10 +255,72 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
})
},
+ make_delivery_note_based_on_delivery_note: function() {
+ var me = this;
+
+ var delivery_dates = [];
+ $.each(this.frm.doc.items || [], function(i, d) {
+ if(!delivery_dates.includes(d.delivery_date)) {
+ delivery_dates.push(d.delivery_date);
+ }
+ });
+
+ var item_grid = this.frm.fields_dict["items"].grid;
+ if(!item_grid.get_selected().length && delivery_dates.length > 1) {
+ var dialog = new frappe.ui.Dialog({
+ title: __("Select Items based on Delivery Date"),
+ fields: [{fieldtype: "HTML", fieldname: "dates_html"}]
+ });
+
+ var html = $(`
+
+
+
+ ${__('Delivery Date')}
+
+
+ ${delivery_dates.map(date => `
+
+
+
+
+
+ `).join("")}
+
+ `);
+
+ var wrapper = dialog.fields_dict.dates_html.$wrapper;
+ wrapper.html(html);
+
+ dialog.set_primary_action(__("Select"), function() {
+ var dates = wrapper.find('input[type=checkbox]:checked')
+ .map((i, el) => $(el).attr('data-date')).toArray();
+
+ if(!dates) return;
+
+ $.each(dates, function(i, d) {
+ $.each(item_grid.grid_rows || [], function(j, row) {
+ if(row.doc.delivery_date == d) {
+ row.doc.__checked = 1;
+ }
+ });
+ })
+ me.make_delivery_note();
+ dialog.hide();
+ });
+ dialog.show();
+ } else {
+ this.make_delivery_note();
+ }
+ },
+
make_delivery_note: function() {
frappe.model.open_mapped_doc({
method: "erpnext.selling.doctype.sales_order.sales_order.make_delivery_note",
- frm: this.frm
+ frm: me.frm
})
},
@@ -344,6 +412,11 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
if(cint(frappe.boot.notification_settings.sales_order)) {
this.frm.email_doc(frappe.boot.notification_settings.sales_order_message);
}
+ },
+
+ items_add: function(doc, cdt, cdn) {
+ var row = frappe.get_doc(cdt, cdn);
+ this.frm.script_manager.copy_from_first_row("items", row, ["delivery_date"]);
}
});
diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json
index 7c995f259a..45365ff846 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.json
+++ b/erpnext/selling/doctype/sales_order/sales_order.json
@@ -367,32 +367,29 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "depends_on": "eval:doc.order_type == 'Sales'",
- "fieldname": "delivery_date",
+ "fieldname": "final_delivery_date",
"fieldtype": "Date",
- "hidden": 0,
+ "hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
- "in_list_view": 0,
+ "in_list_view": 1,
"in_standard_filter": 0,
- "label": "Delivery Date",
+ "label": "Final Delivery Date",
"length": 0,
"no_copy": 1,
- "oldfieldname": "delivery_date",
- "oldfieldtype": "Date",
"permlevel": 0,
- "print_hide": 0,
+ "precision": "",
+ "print_hide": 1,
"print_hide_if_no_value": 0,
- "read_only": 0,
+ "read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "unique": 0,
- "width": "160px"
+ "unique": 0
},
{
"allow_bulk_edit": 0,
@@ -3632,7 +3629,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2017-06-19 13:06:31.736384",
+ "modified": "2017-07-17 18:23:36.023797",
"modified_by": "Administrator",
"module": "Selling",
"name": "Sales Order",
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 4333fd846b..ae63bb3c7d 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -30,7 +30,6 @@ class SalesOrder(SellingController):
self.validate_order_type()
self.validate_delivery_date()
- self.validate_mandatory()
self.validate_proj_cust()
self.validate_po()
self.validate_uom_is_integer("stock_uom", "stock_qty")
@@ -48,25 +47,20 @@ class SalesOrder(SellingController):
if not self.billing_status: self.billing_status = 'Not Billed'
if not self.delivery_status: self.delivery_status = 'Not Delivered'
- def validate_mandatory(self):
- # validate transaction date v/s delivery date
- if self.delivery_date:
- if getdate(self.transaction_date) > getdate(self.delivery_date):
- frappe.msgprint(_("Expected Delivery Date is be before Sales Order Date"),
- indicator='orange',
- title=_('Warning'))
-
def validate_po(self):
# validate p.o date v/s delivery date
- if self.po_date and self.delivery_date and getdate(self.po_date) > getdate(self.delivery_date):
- frappe.throw(_("Expected Delivery Date cannot be before Purchase Order Date"))
+ if self.po_date:
+ for d in self.get("items"):
+ if d.delivery_date and getdate(self.po_date) > getdate(d.delivery_date):
+ frappe.throw(_("Row #{0}: Expected Delivery Date cannot be before Purchase Order Date")
+ .format(d.idx))
if self.po_no and self.customer:
so = frappe.db.sql("select name from `tabSales Order` \
where ifnull(po_no, '') = %s and name != %s and docstatus < 2\
and customer = %s", (self.po_no, self.name, self.customer))
- if so and so[0][0] and not \
- cint(frappe.db.get_single_value("Selling Settings", "allow_against_multiple_purchase_orders")):
+ if so and so[0][0] and not cint(frappe.db.get_single_value("Selling Settings",
+ "allow_against_multiple_purchase_orders")):
frappe.msgprint(_("Warning: Sales Order {0} already exists against Customer's Purchase Order {1}").format(so[0][0], self.po_no))
def validate_for_items(self):
@@ -78,7 +72,7 @@ class SalesOrder(SellingController):
d.transaction_date = self.transaction_date
tot_avail_qty = frappe.db.sql("select projected_qty from `tabBin` \
- where item_code = %s and warehouse = %s", (d.item_code,d.warehouse))
+ where item_code = %s and warehouse = %s", (d.item_code, d.warehouse))
d.projected_qty = tot_avail_qty and flt(tot_avail_qty[0][0]) or 0
# check for same entry multiple times
@@ -97,16 +91,30 @@ class SalesOrder(SellingController):
def validate_sales_mntc_quotation(self):
for d in self.get('items'):
if d.prevdoc_docname:
- res = frappe.db.sql("select name from `tabQuotation` where name=%s and order_type = %s", (d.prevdoc_docname, self.order_type))
+ res = frappe.db.sql("select name from `tabQuotation` where name=%s and order_type = %s",
+ (d.prevdoc_docname, self.order_type))
if not res:
- frappe.msgprint(_("Quotation {0} not of type {1}").format(d.prevdoc_docname, self.order_type))
+ frappe.msgprint(_("Quotation {0} not of type {1}")
+ .format(d.prevdoc_docname, self.order_type))
def validate_order_type(self):
super(SalesOrder, self).validate_order_type()
def validate_delivery_date(self):
- if self.order_type == 'Sales' and not self.delivery_date:
- frappe.throw(_("Please enter 'Expected Delivery Date'"))
+ self.final_delivery_date = None
+ if self.order_type == 'Sales':
+ for d in self.get("items"):
+ if not d.delivery_date:
+ frappe.throw(_("Row #{0}: Please enter Delivery Date against item {1}")
+ .format(d.idx, d.item_code))
+
+ if getdate(self.transaction_date) > getdate(d.delivery_date):
+ frappe.msgprint(_("Expected Delivery Date should be after Sales Order Date"),
+ indicator='orange', title=_('Warning'))
+
+ if not self.final_delivery_date or \
+ (d.delivery_date and getdate(d.delivery_date) > getdate(self.final_delivery_date)):
+ self.final_delivery_date = d.delivery_date
self.validate_sales_mntc_quotation()
@@ -122,7 +130,7 @@ class SalesOrder(SellingController):
super(SalesOrder, self).validate_warehouse()
for d in self.get("items"):
- if (frappe.db.get_value("Item", d.item_code, "is_stock_item")==1 or
+ if (frappe.db.get_value("Item", d.item_code, "is_stock_item") == 1 or
(self.has_product_bundle(d.item_code) and self.product_bundle_has_stock_item(d.item_code))) \
and not d.warehouse and not cint(d.delivered_by_supplier):
frappe.throw(_("Delivery warehouse required for stock item {0}").format(d.item_code),
@@ -336,11 +344,14 @@ class SalesOrder(SellingController):
return items
-
def on_recurring(self, reference_doc):
mcount = month_map[reference_doc.recurring_type]
- self.set("delivery_date", get_next_date(reference_doc.delivery_date, mcount,
- cint(reference_doc.repeat_on_day_of_month)))
+ for d in self.get("items"):
+ reference_delivery_date = frappe.db.get_value("Sales Order Item",
+ {"parent": reference_doc.name, "item_code": d.item_code, "idx": d.idx}, "delivery_date")
+
+ d.set("delivery_date",
+ get_next_date(reference_delivery_date, mcount, cint(reference_doc.repeat_on_day_of_month)))
def get_list_context(context=None):
from erpnext.controllers.website_list_for_contact import get_list_context
@@ -423,7 +434,6 @@ def make_project(source_name, target_doc=None):
},
"field_map":{
"name" : "sales_order",
- "delivery_date" : "expected_end_date",
"base_grand_total" : "estimated_costing",
}
},
@@ -614,12 +624,17 @@ def get_events(start, end, filters=None):
from frappe.desk.calendar import get_event_conditions
conditions = get_event_conditions("Sales Order", filters)
- data = frappe.db.sql("""select name, customer_name, status, delivery_status, billing_status, delivery_date
- from `tabSales Order`
- where (ifnull(delivery_date, '0000-00-00')!= '0000-00-00') \
- and (delivery_date between %(start)s and %(end)s)
- and docstatus < 2
- {conditions}
+ data = frappe.db.sql("""
+ select
+ so.name, so.customer_name, so.status,
+ so.delivery_status, so.billing_status, so_item.delivery_date
+ from
+ `tabSales Order` so, `tabSales Order Item` so_item
+ where so.name = so_item.parent
+ and (ifnull(so_item.delivery_date, '0000-00-00')!= '0000-00-00') \
+ and (so_item.delivery_date between %(start)s and %(end)s)
+ and so.docstatus < 2
+ {conditions}
""".format(conditions=conditions), {
"start": start,
"end": end
@@ -659,7 +674,7 @@ def make_purchase_order_for_drop_shipment(source_name, for_supplier, target_doc=
target.run_method("calculate_taxes_and_totals")
def update_item(source, target, source_parent):
- target.schedule_date = source_parent.delivery_date
+ target.schedule_date = source.delivery_date
target.qty = flt(source.qty) - flt(source.ordered_qty)
target.stock_qty = (flt(source.qty) - flt(source.ordered_qty)) * flt(source.conversion_factor)
diff --git a/erpnext/selling/doctype/sales_order/sales_order_list.js b/erpnext/selling/doctype/sales_order/sales_order_list.js
index d1ac6d92bf..0ee9cf34f0 100644
--- a/erpnext/selling/doctype/sales_order/sales_order_list.js
+++ b/erpnext/selling/doctype/sales_order/sales_order_list.js
@@ -1,14 +1,14 @@
frappe.listview_settings['Sales Order'] = {
- add_fields: ["base_grand_total", "customer_name", "currency", "delivery_date", "per_delivered", "per_billed",
- "status", "order_type"],
+ add_fields: ["base_grand_total", "customer_name", "currency", "final_delivery_date",
+ "per_delivered", "per_billed", "status", "order_type", "name"],
get_indicator: function(doc) {
if(doc.status==="Closed"){
return [__("Closed"), "green", "status,=,Closed"];
} else if (doc.order_type !== "Maintenance"
- && flt(doc.per_delivered, 2) < 100 && frappe.datetime.get_diff(doc.delivery_date) < 0) {
+ && flt(doc.per_delivered, 2) < 100 && frappe.datetime.get_diff(doc.final_delivery_date) < 0) {
// to bill & overdue
- return [__("Overdue"), "red", "per_delivered,<,100|delivery_date,<,Today|status,!=,Closed"];
+ return [__("Overdue"), "red", "per_delivered,<,100|final_delivery_date,<,Today|status,!=,Closed"];
} else if (doc.order_type !== "Maintenance"
&& flt(doc.per_delivered, 2) < 100 && doc.status!=="Closed") {
diff --git a/erpnext/selling/doctype/sales_order/test_records.json b/erpnext/selling/doctype/sales_order/test_records.json
index 12e953a1b6..6cbd6c2fc1 100644
--- a/erpnext/selling/doctype/sales_order/test_records.json
+++ b/erpnext/selling/doctype/sales_order/test_records.json
@@ -7,7 +7,6 @@
"customer": "_Test Customer",
"customer_group": "_Test Customer Group",
"customer_name": "_Test Customer",
- "delivery_date": "2013-02-23",
"doctype": "Sales Order",
"base_grand_total": 1000.0,
"grand_total": 1000.0,
@@ -23,6 +22,7 @@
"doctype": "Sales Order Item",
"item_code": "_Test Item Home Desktop 100",
"item_name": "CPU",
+ "delivery_date": "2013-02-23",
"parentfield": "items",
"qty": 10.0,
"rate": 100.0,
diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.py b/erpnext/selling/doctype/sales_order/test_sales_order.py
index 0417e5e37c..8c0711870b 100644
--- a/erpnext/selling/doctype/sales_order/test_sales_order.py
+++ b/erpnext/selling/doctype/sales_order/test_sales_order.py
@@ -512,7 +512,6 @@ def make_sales_order(**args):
so.company = args.company or "_Test Company"
so.customer = args.customer or "_Test Customer"
- so.delivery_date = add_days(so.transaction_date, 10)
so.currency = args.currency or "INR"
if args.selling_price_list:
so.selling_price_list = args.selling_price_list
@@ -533,6 +532,9 @@ def make_sales_order(**args):
"rate": args.rate or 100
})
+ for d in so.get("items"):
+ d.delivery_date = add_days(so.transaction_date, 10)
+
if not args.do_not_save:
so.insert()
if not args.do_not_submit:
diff --git a/erpnext/selling/doctype/sales_order_item/sales_order_item.json b/erpnext/selling/doctype/sales_order_item/sales_order_item.json
index 2aae9118ff..f14f50dedd 100644
--- a/erpnext/selling/doctype/sales_order_item/sales_order_item.json
+++ b/erpnext/selling/doctype/sales_order_item/sales_order_item.json
@@ -18,7 +18,7 @@
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
- "columns": 4,
+ "columns": 3,
"fieldname": "item_code",
"fieldtype": "Link",
"hidden": 0,
@@ -200,6 +200,36 @@
"unique": 0,
"width": "300px"
},
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 2,
+ "fieldname": "delivery_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Delivery Date",
+ "length": 0,
+ "no_copy": 1,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -324,7 +354,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
- "columns": 2,
+ "columns": 1,
"fieldname": "qty",
"fieldtype": "Float",
"hidden": 0,
@@ -1933,7 +1963,7 @@
"istable": 1,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2017-05-10 17:14:48.277982",
+ "modified": "2017-07-18 18:26:36.870342",
"modified_by": "Administrator",
"module": "Selling",
"name": "Sales Order Item",