From 6b53792aea2554ee0c5bbe2689202eb6b4f995cd Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 14 Mar 2017 16:59:11 +0530 Subject: [PATCH 1/6] [fix] posting date, time is always current unless explicitly set --- .../doctype/sales_invoice/sales_invoice.js | 4 + .../doctype/sales_invoice/sales_invoice.json | 227 ++++++++++-------- .../doctype/purchase_order/purchase_order.js | 2 +- .../production_order/production_order.js | 29 +-- .../production_order_dashboard.py | 11 + .../public/js/controllers/stock_controller.js | 30 +++ erpnext/public/js/controllers/transaction.js | 18 +- .../doctype/delivery_note/delivery_note.js | 225 +++++++++-------- .../doctype/delivery_note/delivery_note.json | 103 +++++--- .../doctype/delivery_note/delivery_note.py | 1 + .../purchase_receipt/purchase_receipt.js | 5 + .../purchase_receipt/purchase_receipt.json | 37 ++- .../purchase_receipt/purchase_receipt.py | 7 +- .../stock/doctype/stock_entry/stock_entry.js | 2 + .../doctype/stock_entry/stock_entry.json | 41 +++- .../stock_reconciliation.js | 6 +- .../stock_reconciliation.json | 34 ++- erpnext/stock/get_item_details.py | 4 +- erpnext/utilities/transaction_base.py | 10 +- 19 files changed, 498 insertions(+), 298 deletions(-) create mode 100644 erpnext/manufacturing/doctype/production_order/production_order_dashboard.py diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js index 1564b48c68e..ddff5d74d6d 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js @@ -8,6 +8,10 @@ cur_frm.pformat.print_heading = 'Invoice'; frappe.provide("erpnext.accounts"); erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.extend({ + setup: function(doc) { + this.setup_posting_date_time_check(); + this._super(doc); + }, onload: function() { var me = this; this._super(); diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json index ae8fd8aff1c..3f9868d5080 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_guest_to_view": 0, "allow_import": 1, "allow_rename": 0, "autoname": "naming_series:", @@ -253,65 +254,6 @@ "set_only_once": 0, "unique": 0 }, - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break1", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "oldfieldtype": "Column Break", - "permlevel": 0, - "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_on_submit": 0, - "bold": 1, - "collapsible": 0, - "columns": 0, - "default": "Today", - "fieldname": "posting_date", - "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Date", - "length": 0, - "no_copy": 1, - "oldfieldname": "posting_date", - "oldfieldtype": "Date", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 1, - "set_only_once": 0, - "unique": 0 - }, { "allow_on_submit": 0, "bold": 0, @@ -342,6 +284,65 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "project", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 1, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Project", + "length": 0, + "no_copy": 0, + "oldfieldname": "project_name", + "oldfieldtype": "Link", + "options": "Project", + "permlevel": 0, + "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_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "column_break1", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "length": 0, + "no_copy": 0, + "oldfieldtype": "Column Break", + "permlevel": 0, + "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_on_submit": 0, "bold": 0, @@ -378,27 +379,87 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "project", - "fieldtype": "Link", + "depends_on": "eval:doc.docstatus==0", + "fieldname": "set_posting_time", + "fieldtype": "Check", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, - "in_global_search": 1, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Project", + "label": "Edit Posting Date and Time", "length": 0, "no_copy": 0, - "oldfieldname": "project_name", - "oldfieldtype": "Link", - "options": "Project", + "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_on_submit": 0, + "bold": 1, + "collapsible": 0, + "columns": 0, + "default": "Today", + "fieldname": "posting_date", + "fieldtype": "Date", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Date", + "length": 0, + "no_copy": 1, + "oldfieldname": "posting_date", + "oldfieldtype": "Date", "permlevel": 0, "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, "remember_last_selected_value": 0, "report_hide": 0, + "reqd": 1, + "search_index": 1, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "posting_time", + "fieldtype": "Time", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Posting Time", + "length": 0, + "no_copy": 1, + "oldfieldname": "posting_time", + "oldfieldtype": "Time", + "permlevel": 0, + "print_hide": 1, + "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, @@ -3558,36 +3619,6 @@ "set_only_once": 0, "unique": 0 }, - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "posting_time", - "fieldtype": "Time", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Posting Time", - "length": 0, - "no_copy": 1, - "oldfieldname": "posting_time", - "oldfieldtype": "Time", - "permlevel": 0, - "print_hide": 1, - "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_on_submit": 0, "bold": 0, @@ -4315,19 +4346,19 @@ "unique": 0 } ], + "has_web_view": 0, "hide_heading": 0, "hide_toolbar": 0, "icon": "fa fa-file-text", "idx": 181, "image_view": 0, "in_create": 0, - "in_dialog": 0, "is_submittable": 1, "issingle": 0, "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2017-02-22 18:20:35.085909", + "modified": "2017-03-14 16:10:33.113402", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice", diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js index 01a9a2ff182..5b16cd64941 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order.js @@ -8,7 +8,7 @@ frappe.provide("erpnext.buying"); frappe.ui.form.on("Purchase Order", { setup: function(frm) { frm.custom_make_buttons = { - 'Purchase Receipt': 'Receive', + 'Purchase Receipt': 'Receipt', 'Purchase Invoice': 'Invoice', 'Stock Entry': 'Material to Supplier' } diff --git a/erpnext/manufacturing/doctype/production_order/production_order.js b/erpnext/manufacturing/doctype/production_order/production_order.js index d8eb25b4c36..7d42f418953 100644 --- a/erpnext/manufacturing/doctype/production_order/production_order.js +++ b/erpnext/manufacturing/doctype/production_order/production_order.js @@ -2,6 +2,12 @@ // License: GNU General Public License v3. See license.txt frappe.ui.form.on("Production Order", { + setup: function(frm) { + frm.custom_make_buttons = { + 'Timesheet': 'Make Timesheet', + 'Stock Entry': 'Make Stock Entry', + } + }, onload: function(frm) { if (!frm.doc.status) frm.doc.status = 'Draft'; @@ -16,7 +22,7 @@ frappe.ui.form.on("Production Order", { }); erpnext.production_order.set_default_warehouse(frm); } - + // formatter for production order operation frm.set_indicator_formatter('operation', function(doc) { return (frm.doc.qty==doc.completed_qty) ? "green" : "orange" }) @@ -27,8 +33,8 @@ frappe.ui.form.on("Production Order", { }, refresh: function(frm) { erpnext.toggle_naming_series(); - frm.set_intro(""); erpnext.production_order.set_custom_buttons(frm); + frm.set_intro(""); if (frm.doc.docstatus === 0 && !frm.doc.__islocal) { frm.set_intro(__("Submit this Production Order for further processing.")); @@ -37,7 +43,7 @@ frappe.ui.form.on("Production Order", { if (frm.doc.docstatus===1) { frm.trigger('show_progress'); } - + if(frm.doc.docstatus == 1 && frm.doc.status != 'Stopped'){ frm.add_custom_button(__('Make Timesheet'), function(){ frappe.model.open_mapped_doc({ @@ -110,34 +116,21 @@ erpnext.production_order = { set_custom_buttons: function(frm) { var doc = frm.doc; if (doc.docstatus === 1) { - frm.add_custom_button(__("Stock Entries"), function() { - frappe.route_options = { - production_order: frm.doc.name - } - frappe.set_route("List", "Stock Entry"); - }, __("View")); - if (doc.status != 'Stopped' && doc.status != 'Completed') { frm.add_custom_button(__('Stop'), cur_frm.cscript['Stop Production Order'], __("Status")); } else if (doc.status == 'Stopped') { frm.add_custom_button(__('Re-open'), cur_frm.cscript['Unstop Production Order'], __("Status")); } - // opertions - if (((doc.operations || []).length) && frm.doc.status != 'Stopped') { - frm.add_custom_button(__('Timesheet'), function() { - frappe.route_options = {"production_order": frm.doc.name}; - frappe.set_route("List", "Timesheet"); - }, __("View")); - } - if ((flt(doc.material_transferred_for_manufacturing) < flt(doc.qty)) && frm.doc.status != 'Stopped') { + frm.has_start_btn = true; var btn = frm.add_custom_button(__('Start'), cur_frm.cscript['Transfer Raw Materials']); btn.addClass('btn-primary'); } if ((flt(doc.produced_qty) < flt(doc.material_transferred_for_manufacturing)) && frm.doc.status != 'Stopped') { + frm.has_finish_btn = true; var btn = frm.add_custom_button(__('Finish'), cur_frm.cscript['Update Finished Goods']); diff --git a/erpnext/manufacturing/doctype/production_order/production_order_dashboard.py b/erpnext/manufacturing/doctype/production_order/production_order_dashboard.py new file mode 100644 index 00000000000..7c8c8c64b96 --- /dev/null +++ b/erpnext/manufacturing/doctype/production_order/production_order_dashboard.py @@ -0,0 +1,11 @@ +from frappe import _ + +def get_data(): + return { + 'fieldname': 'production_order', + 'transactions': [ + { + 'items': ['Stock Entry', 'Timesheet'] + } + ] + } \ No newline at end of file diff --git a/erpnext/public/js/controllers/stock_controller.js b/erpnext/public/js/controllers/stock_controller.js index a360d919be4..cf1f1e97a5c 100644 --- a/erpnext/public/js/controllers/stock_controller.js +++ b/erpnext/public/js/controllers/stock_controller.js @@ -18,6 +18,36 @@ erpnext.stock.StockController = frappe.ui.form.Controller.extend({ }); }, + setup_posting_date_time_check: function() { + // make posting date default and read only unless explictly checked + frappe.ui.form.on(this.frm.doctype, 'set_posting_date_and_time_read_only', function(frm) { + if(frm.doc.docstatus == 0 && frm.doc.set_posting_time) { + frm.set_df_property('posting_date', 'read_only', 0); + frm.set_df_property('posting_time', 'read_only', 0); + } else { + frm.set_df_property('posting_date', 'read_only', 1); + frm.set_df_property('posting_time', 'read_only', 1); + } + }) + + frappe.ui.form.on(this.frm.doctype, 'set_posting_time', function(frm) { + frm.trigger('set_posting_date_and_time_read_only'); + }); + + frappe.ui.form.on(this.frm.doctype, 'refresh', function(frm) { + // set default posting date / time + if(frm.doc.docstatus==0) { + if(!frm.doc.posting_date) { + frm.set_value('posting_date', frappe.datetime.nowdate()); + } + if(!frm.doc.posting_time) { + frm.set_value('posting_time', frappe.datetime.now_time()); + } + frm.trigger('set_posting_date_and_time_read_only'); + } + }); + }, + show_stock_ledger: function() { var me = this; if(this.frm.doc.docstatus===1) { diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 02732d24611..fb5ff54a579 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -134,7 +134,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ } }); } - + this.setup_quality_inspection(); }, @@ -143,9 +143,9 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ return; } var me = this; - var inspection_type = in_list(["Purchase Receipt", "Purchase Invoice"], this.frm.doc.doctype) + var inspection_type = in_list(["Purchase Receipt", "Purchase Invoice"], this.frm.doc.doctype) ? "Incoming" : "Outgoing"; - + var quality_inspection_field = this.frm.get_docfield("items", "quality_inspection"); quality_inspection_field.get_route_options_for_new_doc = function(row) { if(me.frm.is_new()) return; @@ -159,7 +159,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ "batch_no": row.doc.batch_no } } - + this.frm.set_query("quality_inspection", "items", function(doc, cdt, cdn) { var d = locals[cdt][cdn]; return { @@ -319,7 +319,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ refresh_field("serial_no", item.name, item.parentfield); if(!doc.is_return) { - frappe.model.set_value(item.doctype, item.name, + frappe.model.set_value(item.doctype, item.name, "qty", sr_no.length / item.conversion_factor); frappe.model.set_value(item.doctype, item.name, "stock_qty", sr_no.length); } @@ -460,7 +460,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ /* manqala 19/09/2016: let the translation date be whichever of the transaction_date or posting_date is available */ var transaction_date = this.frm.doc.transaction_date || this.frm.doc.posting_date; /* end manqala */ - + var me = this; this.set_dynamic_labels(); @@ -596,7 +596,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ this.frm.set_currency_labels(["base_total", "base_net_total", "base_total_taxes_and_charges", "base_discount_amount", "base_grand_total", "base_rounded_total", "base_in_words", "base_taxes_and_charges_added", "base_taxes_and_charges_deducted", "total_amount_to_pay", - "base_paid_amount", "base_write_off_amount", "base_change_amount", "base_operating_cost", + "base_paid_amount", "base_write_off_amount", "base_change_amount", "base_operating_cost", "base_raw_material_cost", "base_total_cost", "base_scrap_material_cost" ], company_currency); @@ -619,7 +619,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ this.frm.toggle_display(["conversion_rate", "base_total", "base_net_total", "base_total_taxes_and_charges", "base_taxes_and_charges_added", "base_taxes_and_charges_deducted", "base_grand_total", "base_rounded_total", "base_in_words", "base_discount_amount", - "base_paid_amount", "base_write_off_amount", "base_operating_cost", + "base_paid_amount", "base_write_off_amount", "base_operating_cost", "base_raw_material_cost", "base_total_cost", "base_scrap_material_cost"], this.frm.doc.currency != company_currency); @@ -1080,5 +1080,5 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ return method }, - + }); \ No newline at end of file diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.js b/erpnext/stock/doctype/delivery_note/delivery_note.js index 4705be6d3c8..976cfc86fff 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.js +++ b/erpnext/stock/doctype/delivery_note/delivery_note.js @@ -21,31 +21,98 @@ frappe.ui.form.on("Delivery Note", { erpnext.queries.setup_warehouse_query(frm); + frm.set_query('project', function(doc) { + return { + query: "erpnext.controllers.queries.get_project_name", + filters: { + 'customer': doc.customer + } + } + }) + + frm.set_query('transporter_name', function(doc) { + return { + filters: { 'supplier_type': "transporter" } + } + }); + + if (sys_defaults.auto_accounting_for_stock) { + frm.set_query('expense_account', 'items', function(frm) { + return { + filters: { + "report_type": "Profit and Loss", + "company": doc.company, + "is_group": 0 + } + } + }); + + frm.set_query('cost_center', 'items', function(frm) { + return { + filters: { + 'company': doc.company, + "is_group": 0 + } + } + }); + } + + $.extend(frm.cscript, new erpnext.stock.DeliveryNoteController({frm: frm})); + }, + print_without_amount: function(frm) { + erpnext.stock.delivery_note.set_print_hide(frm.doc); + }, + on_submit: function(frm) { + if(cint(frappe.boot.notification_settings.delivery_note)) { + frm.email_doc(frappe.boot.notification_settings.delivery_note_message); + } } }); +frappe.ui.form.on("Delivery Note Item", { + expense_account: function(frm, dt, dn) { + var d = locals[dt][dn]; + frm.update_in_all_rows('items', 'expense_account', d.expense_account); + }, + cost_center: function(frm, dt, dn) { + var d = locals[dt][dn]; + frm.update_in_all_rows('items', 'cost_center', d.cost_center); + } +}); + + erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend({ + setup: function(doc) { + this.setup_posting_date_time_check(); + this._super(doc); + }, refresh: function(doc, dt, dn) { + var me = this; this._super(); if (!doc.is_return && doc.status!="Closed") { if(flt(doc.per_installed, 2) < 100 && doc.docstatus==1) - cur_frm.add_custom_button(__('Installation Note'), this.make_installation_note, __("Make")); + this.frm.add_custom_button(__('Installation Note'), function() { + me.make_installation_note() }, __("Make")); if (doc.docstatus==1) { - cur_frm.add_custom_button(__('Sales Return'), this.make_sales_return, __("Make")); + this.frm.add_custom_button(__('Sales Return'), function() { + me.make_sales_return() }, __("Make")); } if(doc.docstatus==0 && !doc.__islocal) { - cur_frm.add_custom_button(__('Packing Slip'), - cur_frm.cscript['Make Packing Slip'], __("Make")); + this.frm.add_custom_button(__('Packing Slip'), function() { + frappe.model.open_mapped_doc({ + method: "erpnext.stock.doctype.delivery_note.delivery_note.make_packing_slip", + frm: me.frm + }) }, __("Make")); } if (!doc.__islocal && doc.docstatus==1) { - cur_frm.page.set_inner_btn_group_as_primary(__("Make")); + this.frm.page.set_inner_btn_group_as_primary(__("Make")); } if (this.frm.doc.docstatus===0) { - cur_frm.add_custom_button(__('Sales Order'), + this.frm.add_custom_button(__('Sales Order'), function() { erpnext.utils.map_current_doc({ method: "erpnext.selling.doctype.sales_order.sales_order.make_delivery_note", @@ -54,9 +121,9 @@ erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend( docstatus: 1, status: ["!=", "Closed"], per_delivered: ["<", 99.99], - project: cur_frm.doc.project || undefined, - customer: cur_frm.doc.customer || undefined, - company: cur_frm.doc.company + project: me.frm.doc.project || undefined, + customer: me.frm.doc.customer || undefined, + company: me.frm.doc.company } }) }, __("Get items from")); @@ -69,49 +136,53 @@ erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend( this.show_general_ledger(); } if (this.frm.has_perm("submit") && doc.status !== "Closed") { - cur_frm.add_custom_button(__("Close"), this.close_delivery_note, __("Status")) + me.frm.add_custom_button(__("Close"), function() { me.close_delivery_note() }, + __("Status")) } } if(doc.docstatus==1 && !doc.is_return && doc.status!="Closed" && flt(doc.per_billed) < 100) { // show Make Invoice button only if Delivery Note is not created from Sales Invoice var from_sales_invoice = false; - from_sales_invoice = cur_frm.doc.items.some(function(item) { + from_sales_invoice = me.frm.doc.items.some(function(item) { return item.against_sales_invoice ? true : false; }); - if(!from_sales_invoice) - cur_frm.add_custom_button(__('Invoice'), this.make_sales_invoice, __("Make")); + if(!from_sales_invoice) { + this.frm.add_custom_button(__('Invoice'), function() { me.make_sales_invoice() }, + __("Make")); + } } if(doc.docstatus==1 && doc.status === "Closed" && this.frm.has_perm("submit")) { - cur_frm.add_custom_button(__('Reopen'), this.reopen_delivery_note, __("Status")) + this.frm.add_custom_button(__('Reopen'), function() { me.reopen_delivery_note() }, + __("Status")) } erpnext.stock.delivery_note.set_print_hide(doc, dt, dn); // unhide expense_account and cost_center is auto_accounting_for_stock enabled var aii_enabled = cint(sys_defaults.auto_accounting_for_stock) - cur_frm.fields_dict["items"].grid.set_column_disp(["expense_account", "cost_center"], aii_enabled); + this.frm.fields_dict["items"].grid.set_column_disp(["expense_account", "cost_center"], aii_enabled); }, make_sales_invoice: function() { frappe.model.open_mapped_doc({ method: "erpnext.stock.doctype.delivery_note.delivery_note.make_sales_invoice", - frm: cur_frm + frm: this.frm }) }, make_installation_note: function() { frappe.model.open_mapped_doc({ method: "erpnext.stock.doctype.delivery_note.delivery_note.make_installation_note", - frm: cur_frm + frm: this.frm }); }, make_sales_return: function() { frappe.model.open_mapped_doc({ method: "erpnext.stock.doctype.delivery_note.delivery_note.make_sales_return", - frm: cur_frm + frm: this.frm }) }, @@ -124,56 +195,31 @@ erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend( }, close_delivery_note: function(doc){ - cur_frm.cscript.update_status("Closed") + this.update_status("Closed") }, reopen_delivery_note : function() { - cur_frm.cscript.update_status("Submitted") + this.update_status("Submitted") + }, + + update_status: function(status) { + var me = this; + frappe.ui.form.is_saving = true; + frappe.call({ + method:"erpnext.stock.doctype.delivery_note.delivery_note.update_delivery_note_status", + args: {docname: me.frm.doc.name, status: status}, + callback: function(r){ + if(!r.exc) + me.frm.reload_doc(); + }, + always: function(){ + frappe.ui.form.is_saving = false; + } + }) } }); -// for backward compatibility: combine new and previous states -$.extend(cur_frm.cscript, new erpnext.stock.DeliveryNoteController({frm: cur_frm})); - - -cur_frm.cscript.update_status = function(status) { - frappe.ui.form.is_saving = true; - frappe.call({ - method:"erpnext.stock.doctype.delivery_note.delivery_note.update_delivery_note_status", - args: {docname: cur_frm.doc.name, status: status}, - callback: function(r){ - if(!r.exc) - cur_frm.reload_doc(); - }, - always: function(){ - frappe.ui.form.is_saving = false; - } - }) -} - -// ***************** Get project name ***************** -cur_frm.fields_dict['project'].get_query = function(doc, cdt, cdn) { - return { - query: "erpnext.controllers.queries.get_project_name", - filters: { - 'customer': doc.customer - } - } -} - -cur_frm.fields_dict['transporter_name'].get_query = function(doc) { - return{ - filters: { 'supplier_type': "transporter" } - } -} - -cur_frm.cscript['Make Packing Slip'] = function() { - frappe.model.open_mapped_doc({ - method: "erpnext.stock.doctype.delivery_note.delivery_note.make_packing_slip", - frm: cur_frm - }) -} erpnext.stock.delivery_note.set_print_hide = function(doc, cdt, cdn){ var dn_fields = frappe.meta.docfield_map['Delivery Note']; @@ -199,60 +245,3 @@ erpnext.stock.delivery_note.set_print_hide = function(doc, cdt, cdn){ dn_fields['taxes'].print_hide = 0; } } - -cur_frm.cscript.print_without_amount = function(doc, cdt, cdn) { - erpnext.stock.delivery_note.set_print_hide(doc, cdt, cdn); -} - -cur_frm.cscript.on_submit = function(doc, cdt, cdn) { - if(cint(frappe.boot.notification_settings.delivery_note)) { - cur_frm.email_doc(frappe.boot.notification_settings.delivery_note_message); - } -} - -if (sys_defaults.auto_accounting_for_stock) { - - cur_frm.cscript.expense_account = function(doc, cdt, cdn){ - var d = locals[cdt][cdn]; - if(d.expense_account) { - var cl = doc["items"] || []; - for(var i = 0; i < cl.length; i++){ - if(!cl[i].expense_account) cl[i].expense_account = d.expense_account; - } - } - refresh_field("items"); - } - - // expense account - cur_frm.fields_dict['items'].grid.get_field('expense_account').get_query = function(doc) { - return { - filters: { - "report_type": "Profit and Loss", - "company": doc.company, - "is_group": 0 - } - } - } - - // cost center - cur_frm.cscript.cost_center = function(doc, cdt, cdn){ - var d = locals[cdt][cdn]; - if(d.cost_center) { - var cl = doc["items"] || []; - for(var i = 0; i < cl.length; i++){ - if(!cl[i].cost_center) cl[i].cost_center = d.cost_center; - } - } - refresh_field("items"); - } - - cur_frm.fields_dict.items.grid.get_field("cost_center").get_query = function(doc) { - return { - - filters: { - 'company': doc.company, - "is_group": 0 - } - } - } -} diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.json b/erpnext/stock/doctype/delivery_note/delivery_note.json index e0deb1b2c37..a85a9642901 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.json +++ b/erpnext/stock/doctype/delivery_note/delivery_note.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_guest_to_view": 0, "allow_import": 1, "allow_rename": 0, "autoname": "naming_series:", @@ -286,12 +287,43 @@ "unique": 0, "width": "150px" }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:doc.docstatus==0", + "fieldname": "set_posting_time", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Edit Posting Date and Time", + "length": 0, + "no_copy": 0, + "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_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, "default": "Today", + "depends_on": "", "fieldname": "posting_date", "fieldtype": "Date", "hidden": 0, @@ -319,6 +351,40 @@ "unique": 0, "width": "100px" }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "", + "description": "", + "fieldname": "posting_time", + "fieldtype": "Time", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Posting Time", + "length": 0, + "no_copy": 0, + "oldfieldname": "posting_time", + "oldfieldtype": "Time", + "permlevel": 0, + "print_hide": 1, + "print_hide_if_no_value": 0, + "print_width": "100px", + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0, + "width": "100px" + }, { "allow_on_submit": 0, "bold": 0, @@ -2516,39 +2582,6 @@ "unique": 0, "width": "50%" }, - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "description": "Time at which items were delivered from warehouse", - "fieldname": "posting_time", - "fieldtype": "Time", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Posting Time", - "length": 0, - "no_copy": 0, - "oldfieldname": "posting_time", - "oldfieldtype": "Time", - "permlevel": 0, - "print_hide": 1, - "print_hide_if_no_value": 0, - "print_width": "100px", - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0, - "width": "100px" - }, { "allow_on_submit": 0, "bold": 0, @@ -3214,19 +3247,19 @@ "unique": 0 } ], + "has_web_view": 0, "hide_heading": 0, "hide_toolbar": 0, "icon": "fa fa-truck", "idx": 146, "image_view": 0, "in_create": 0, - "in_dialog": 0, "is_submittable": 1, "issingle": 0, "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2017-02-20 13:29:16.788934", + "modified": "2017-03-14 16:57:42.173938", "modified_by": "Administrator", "module": "Stock", "name": "Delivery Note", diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py index 3b2c44c8b7b..5e8f5c9b46a 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/delivery_note.py @@ -94,6 +94,7 @@ class DeliveryNote(SellingController): frappe.throw(_("Sales Order required for Item {0}").format(d.item_code)) def validate(self): + self.validate_posting_time() super(DeliveryNote, self).validate() self.set_status() self.so_required() diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js index a96ff6ebf82..f9370b43675 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js @@ -37,6 +37,11 @@ frappe.ui.form.on("Purchase Receipt", { }); erpnext.stock.PurchaseReceiptController = erpnext.buying.BuyingController.extend({ + setup: function(doc) { + this.setup_posting_date_time_check(); + this._super(doc); + }, + refresh: function() { this._super(); if(this.frm.doc.docstatus===1) { diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json index 2e8cd1a6593..73367e3fab3 100755 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_guest_to_view": 0, "allow_import": 1, "allow_rename": 0, "autoname": "naming_series:", @@ -224,12 +225,43 @@ "unique": 0, "width": "50%" }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:doc.docstatus==0", + "fieldname": "set_posting_time", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Edit Posting Date and Time", + "length": 0, + "no_copy": 0, + "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_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, "default": "Today", + "depends_on": "", "fieldname": "posting_date", "fieldtype": "Date", "hidden": 0, @@ -262,6 +294,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "depends_on": "", "description": "Time at which materials were received", "fieldname": "posting_time", "fieldtype": "Time", @@ -2801,19 +2834,19 @@ "width": "100px" } ], + "has_web_view": 0, "hide_heading": 0, "hide_toolbar": 0, "icon": "fa fa-truck", "idx": 261, "image_view": 0, "in_create": 0, - "in_dialog": 0, "is_submittable": 1, "issingle": 0, "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2017-02-20 13:30:17.979040", + "modified": "2017-03-14 16:10:58.769483", "modified_by": "Administrator", "module": "Stock", "name": "Purchase Receipt", diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index 4bcde6a49af..b89987c57e6 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -46,8 +46,9 @@ class PurchaseReceipt(BuyingController): }] def validate(self): + self.validate_posting_time() super(PurchaseReceipt, self).validate() - + if not self._action=="submit": self.set_status() self.po_required() @@ -57,10 +58,10 @@ class PurchaseReceipt(BuyingController): pc_obj = frappe.get_doc('Purchase Common') self.check_for_closed_status(pc_obj) - + if getdate(self.posting_date) > getdate(nowdate()): throw(_("Posting Date cannot be future date")) - + def validate_with_previous_doc(self): super(PurchaseReceipt, self).validate_with_previous_doc({ diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js index 8f6c592a451..864f9b135dd 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.js +++ b/erpnext/stock/doctype/stock_entry/stock_entry.js @@ -188,6 +188,8 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ setup: function() { var me = this; + this.setup_posting_date_time_check(); + this.frm.fields_dict.bom_no.get_query = function() { return { filters:{ diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.json b/erpnext/stock/doctype/stock_entry/stock_entry.json index e0833c5fb2d..a6dd8255013 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.json +++ b/erpnext/stock/doctype/stock_entry/stock_entry.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_guest_to_view": 0, "allow_import": 1, "allow_rename": 0, "autoname": "naming_series:", @@ -382,12 +383,43 @@ "unique": 0, "width": "50%" }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:doc.docstatus==0", + "fieldname": "set_posting_time", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Edit Posting Date and Time", + "length": 0, + "no_copy": 0, + "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_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, "default": "Today", + "depends_on": "", "fieldname": "posting_date", "fieldtype": "Date", "hidden": 0, @@ -408,7 +440,7 @@ "read_only": 0, "remember_last_selected_value": 0, "report_hide": 0, - "reqd": 1, + "reqd": 0, "search_index": 1, "set_only_once": 0, "unique": 0 @@ -418,6 +450,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "depends_on": "", "fieldname": "posting_time", "fieldtype": "Time", "hidden": 0, @@ -438,7 +471,7 @@ "read_only": 0, "remember_last_selected_value": 0, "report_hide": 0, - "reqd": 1, + "reqd": 0, "search_index": 0, "set_only_once": 0, "unique": 0 @@ -1610,18 +1643,18 @@ "unique": 0 } ], + "has_web_view": 0, "hide_heading": 0, "hide_toolbar": 0, "icon": "fa fa-file-text", "idx": 1, "image_view": 0, "in_create": 0, - "in_dialog": 0, "is_submittable": 1, "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2017-02-20 13:27:59.670920", + "modified": "2017-03-14 16:11:11.741704", "modified_by": "Administrator", "module": "Stock", "name": "Stock Entry", diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js index 2b031d1c2f4..7ed4ede8aa0 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js @@ -77,7 +77,7 @@ frappe.ui.form.on("Stock Reconciliation", { frappe.model.set_value(cdt, cdn, "current_valuation_rate", r.message.rate); frappe.model.set_value(cdt, cdn, "current_amount", r.message.rate * r.message.qty); frappe.model.set_value(cdt, cdn, "amount", r.message.rate * r.message.qty); - + } }); } @@ -122,7 +122,7 @@ frappe.ui.form.on("Stock Reconciliation Item", { valuation_rate: function(frm, cdt, cdn) { frm.events.set_amount_quantity(frm, cdt, cdn); } - + }); erpnext.stock.StockReconciliation = erpnext.stock.StockController.extend({ @@ -154,6 +154,8 @@ erpnext.stock.StockReconciliation = erpnext.stock.StockController.extend({ var me = this; this.frm.get_docfield("items").allow_bulk_edit = 1; + this.setup_posting_date_time_check(); + if (sys_defaults.auto_accounting_for_stock) { this.frm.add_fetch("company", "stock_adjustment_account", "expense_account"); this.frm.add_fetch("company", "cost_center", "cost_center"); diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json index 41a1679d0a7..cd3c3e25c17 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, "autoname": "naming_series:", @@ -41,6 +42,35 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "set_posting_time", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Edit Posting Date and Time", + "length": 0, + "no_copy": 0, + "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_on_submit": 0, "bold": 0, @@ -419,19 +449,19 @@ "unique": 0 } ], + "has_web_view": 0, "hide_heading": 0, "hide_toolbar": 0, "icon": "fa fa-upload-alt", "idx": 1, "image_view": 0, "in_create": 0, - "in_dialog": 0, "is_submittable": 1, "issingle": 0, "istable": 0, "max_attachments": 1, "menu_index": 0, - "modified": "2017-02-20 13:31:41.489372", + "modified": "2017-03-14 15:55:38.016195", "modified_by": "Administrator", "module": "Stock", "name": "Stock Reconciliation", diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index be20a810c2b..958da16bac2 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -62,7 +62,7 @@ def get_item_details(args): if args.customer and cint(args.is_pos): out.update(get_pos_profile_item_details(args.company, args)) - + if out.get("warehouse"): out.update(get_bin_details(args.item_code, out.warehouse)) @@ -482,7 +482,7 @@ def get_price_list_currency_and_exchange_rate(args): if (not plc_conversion_rate) or (price_list_currency and args.price_list_currency \ and price_list_currency != args.price_list_currency): - # cksgb 19/09/2016: added args.transaction_date as posting_date argument for get_exchange_rate + # cksgb 19/09/2016: added args.transaction_date as posting_date argument for get_exchange_rate plc_conversion_rate = get_exchange_rate(price_list_currency, args.currency, args.transaction_date) or plc_conversion_rate diff --git a/erpnext/utilities/transaction_base.py b/erpnext/utilities/transaction_base.py index 2d6cbc06f41..d447482956e 100644 --- a/erpnext/utilities/transaction_base.py +++ b/erpnext/utilities/transaction_base.py @@ -18,8 +18,10 @@ class TransactionBase(StatusUpdater): frappe.db.get_value("Notification Control", None, dt + "_message")) def validate_posting_time(self): - if not self.posting_time: - self.posting_time = now_datetime().strftime('%H:%M:%S') + if not getattr(self, 'set_posting_time', False): + now = now_datetime() + self.posting_date = now.strftime('%Y-%m-%d') + self.posting_time = now.strftime('%H:%M:%S') def add_calendar_event(self, opts, force=False): if cstr(self.contact_by) != cstr(self._prev.contact_by) or \ @@ -107,7 +109,7 @@ class TransactionBase(StatusUpdater): def get_link_filters(self, for_doctype): if hasattr(self, "prev_link_mapper") and self.prev_link_mapper.get(for_doctype): fieldname = self.prev_link_mapper[for_doctype]["fieldname"] - + values = filter(None, tuple([item.as_dict()[fieldname] for item in self.items])) if values: @@ -120,7 +122,7 @@ class TransactionBase(StatusUpdater): ret = None else: ret = None - + return ret def delete_events(ref_type, ref_name): From 6d4a52562bdf19c2e231994adeb67a3afbaf3343 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 14 Mar 2017 17:05:06 +0530 Subject: [PATCH 2/6] [fix] posting date, time is always current unless explicitly set --- .../purchase_invoice/purchase_invoice.js | 4 + .../purchase_invoice/purchase_invoice.json | 97 ++++++++++++------- .../purchase_invoice/purchase_invoice.py | 5 +- erpnext/buying/doctype/supplier/supplier.json | 7 +- erpnext/hr/doctype/employee/employee.json | 7 +- erpnext/setup/doctype/company/company.json | 8 +- 6 files changed, 83 insertions(+), 45 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js index 55ece1c35f4..f79d533d51e 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js @@ -6,6 +6,10 @@ frappe.provide("erpnext.accounts"); erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({ + setup: function(doc) { + this.setup_posting_date_time_check(); + this._super(doc); + }, onload: function() { this._super(); diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json index ff3a1686e3f..2e3fbde4ab3 100755 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_guest_to_view": 0, "allow_import": 1, "allow_rename": 0, "autoname": "naming_series:", @@ -253,6 +254,36 @@ "unique": 0, "width": "50%" }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:doc.docstatus==0", + "fieldname": "set_posting_time", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Edit Posting Date and Time", + "length": 0, + "no_copy": 0, + "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_on_submit": 0, "bold": 0, @@ -284,6 +315,37 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "posting_time", + "fieldtype": "Time", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Posting Time", + "length": 0, + "no_copy": 1, + "permlevel": 0, + "precision": "", + "print_hide": 1, + "print_hide_if_no_value": 0, + "print_width": "100px", + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0, + "width": "100px" + }, { "allow_on_submit": 0, "bold": 0, @@ -3000,37 +3062,6 @@ "set_only_once": 0, "unique": 0 }, - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "posting_time", - "fieldtype": "Time", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Posting Time", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "precision": "", - "print_hide": 1, - "print_hide_if_no_value": 0, - "print_width": "100px", - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0, - "width": "100px" - }, { "allow_on_submit": 0, "bold": 0, @@ -3515,19 +3546,19 @@ "unique": 0 } ], + "has_web_view": 0, "hide_heading": 0, "hide_toolbar": 0, "icon": "fa fa-file-text", "idx": 204, "image_view": 0, "in_create": 0, - "in_dialog": 0, "is_submittable": 1, "issingle": 0, "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2017-02-22 18:16:09.890488", + "modified": "2017-03-14 17:00:07.106802", "modified_by": "Administrator", "module": "Accounts", "name": "Purchase Invoice", diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index c0693d14a6d..ae74d6225f3 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -40,6 +40,7 @@ class PurchaseInvoice(BuyingController): if not self.is_opening: self.is_opening = 'No' + self.validate_posting_time() super(PurchaseInvoice, self).validate() if not self.is_return: @@ -307,7 +308,7 @@ class PurchaseInvoice(BuyingController): return if not gl_entries: gl_entries = self.get_gl_entries() - + if gl_entries: update_outstanding = "No" if (cint(self.is_paid) or self.write_off_account) else "Yes" @@ -344,7 +345,7 @@ class PurchaseInvoice(BuyingController): self.make_payment_gl_entries(gl_entries) self.make_write_off_gl_entry(gl_entries) - + return gl_entries def make_supplier_gl_entry(self, gl_entries): diff --git a/erpnext/buying/doctype/supplier/supplier.json b/erpnext/buying/doctype/supplier/supplier.json index 76f28ae8927..9adb42bb071 100644 --- a/erpnext/buying/doctype/supplier/supplier.json +++ b/erpnext/buying/doctype/supplier/supplier.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_guest_to_view": 0, "allow_import": 1, "allow_rename": 1, "autoname": "naming_series:", @@ -781,6 +782,7 @@ "unique": 0 } ], + "has_web_view": 0, "hide_heading": 0, "hide_toolbar": 0, "icon": "fa fa-user", @@ -788,12 +790,11 @@ "image_field": "image", "image_view": 0, "in_create": 0, - "in_dialog": 0, "is_submittable": 0, "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2017-02-17 16:46:48.202078", + "modified": "2017-03-14 17:04:17.785461", "modified_by": "Administrator", "module": "Buying", "name": "Supplier", @@ -948,6 +949,6 @@ "show_name_in_global_search": 1, "sort_order": "ASC", "title_field": "supplier_name", - "track_changes": 0, + "track_changes": 1, "track_seen": 0 } \ No newline at end of file diff --git a/erpnext/hr/doctype/employee/employee.json b/erpnext/hr/doctype/employee/employee.json index 80e484d6617..35a28078d0b 100644 --- a/erpnext/hr/doctype/employee/employee.json +++ b/erpnext/hr/doctype/employee/employee.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_guest_to_view": 0, "allow_import": 1, "allow_rename": 1, "autoname": "naming_series:", @@ -2340,6 +2341,7 @@ "unique": 0 } ], + "has_web_view": 0, "hide_heading": 0, "hide_toolbar": 0, "icon": "fa fa-user", @@ -2347,12 +2349,11 @@ "image_field": "image", "image_view": 0, "in_create": 0, - "in_dialog": 0, "is_submittable": 0, "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2017-02-17 16:56:25.571268", + "modified": "2017-03-14 17:04:27.247238", "modified_by": "Administrator", "module": "HR", "name": "Employee", @@ -2428,6 +2429,6 @@ "sort_field": "modified", "sort_order": "DESC", "title_field": "employee_name", - "track_changes": 0, + "track_changes": 1, "track_seen": 0 } \ No newline at end of file diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json index 7497a81e343..9c97b8edec2 100644 --- a/erpnext/setup/doctype/company/company.json +++ b/erpnext/setup/doctype/company/company.json @@ -408,7 +408,7 @@ "label": "Create Chart Of Accounts Based On", "length": 0, "no_copy": 0, - "options": "\nStandard Template\nExisting Company", + "options": "Standard Template\nExisting Company", "permlevel": 0, "precision": "", "print_hide": 0, @@ -416,7 +416,7 @@ "read_only": 0, "remember_last_selected_value": 0, "report_hide": 0, - "reqd": 1, + "reqd": 0, "search_index": 0, "set_only_once": 0, "unique": 0 @@ -1693,7 +1693,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2017-03-12 15:50:23.099622", + "modified": "2017-03-14 17:04:38.115970", "modified_by": "Administrator", "module": "Setup", "name": "Company", @@ -1845,6 +1845,6 @@ "read_only_onload": 0, "show_name_in_global_search": 1, "sort_order": "ASC", - "track_changes": 0, + "track_changes": 1, "track_seen": 0 } \ No newline at end of file From f6dee248ee6273cf86a23b4ba5157b190cf5457f Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 14 Mar 2017 17:10:01 +0530 Subject: [PATCH 3/6] Update company.json --- erpnext/setup/doctype/company/company.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json index 9c97b8edec2..60268a983ef 100644 --- a/erpnext/setup/doctype/company/company.json +++ b/erpnext/setup/doctype/company/company.json @@ -408,7 +408,7 @@ "label": "Create Chart Of Accounts Based On", "length": 0, "no_copy": 0, - "options": "Standard Template\nExisting Company", + "options": "\nStandard Template\nExisting Company", "permlevel": 0, "precision": "", "print_hide": 0, @@ -1847,4 +1847,4 @@ "sort_order": "ASC", "track_changes": 1, "track_seen": 0 -} \ No newline at end of file +} From 82c258948d1f0df50989d3af33d6da96bce08337 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 14 Mar 2017 18:52:47 +0530 Subject: [PATCH 4/6] [fixes] for recurring and tests --- erpnext/accounts/doctype/asset/asset.py | 61 +++++++------- .../doctype/payment_entry/payment_entry.json | 7 +- .../sales_invoice/test_sales_invoice.py | 2 + erpnext/controllers/recurring_document.py | 3 + .../delivery_note/test_delivery_note.py | 80 ++++++++++--------- .../doctype/stock_entry/test_stock_entry.py | 9 ++- .../test_stock_reconciliation.py | 3 +- 7 files changed, 88 insertions(+), 77 deletions(-) diff --git a/erpnext/accounts/doctype/asset/asset.py b/erpnext/accounts/doctype/asset/asset.py index b8d0ec8170a..a99a8cff063 100644 --- a/erpnext/accounts/doctype/asset/asset.py +++ b/erpnext/accounts/doctype/asset/asset.py @@ -32,7 +32,7 @@ class Asset(Document): self.set_status() def validate_item(self): - item = frappe.db.get_value("Item", self.item_code, + item = frappe.db.get_value("Item", self.item_code, ["is_fixed_asset", "is_stock_item", "disabled"], as_dict=1) if not item: frappe.throw(_("Item {0} does not exist").format(self.item_code)) @@ -42,7 +42,7 @@ class Asset(Document): frappe.throw(_("Item {0} must be a Fixed Asset Item").format(self.item_code)) elif item.is_stock_item: frappe.throw(_("Item {0} must be a non-stock item").format(self.item_code)) - + def set_missing_values(self): if self.item_code: item_details = get_item_details(self.item_code) @@ -50,7 +50,7 @@ class Asset(Document): if not self.get(field): self.set(field, value) - self.value_after_depreciation = (flt(self.gross_purchase_amount) - + self.value_after_depreciation = (flt(self.gross_purchase_amount) - flt(self.opening_accumulated_depreciation)) def validate_asset_values(self): @@ -59,7 +59,7 @@ class Asset(Document): if not flt(self.gross_purchase_amount): frappe.throw(_("Gross Purchase Amount is mandatory"), frappe.MandatoryError) - + if not self.is_existing_asset: self.opening_accumulated_depreciation = 0 self.number_of_depreciations_booked = 0 @@ -70,33 +70,33 @@ class Asset(Document): if flt(self.opening_accumulated_depreciation) > depreciable_amount: frappe.throw(_("Opening Accumulated Depreciation must be less than equal to {0}") .format(depreciable_amount)) - + if self.opening_accumulated_depreciation: if not self.number_of_depreciations_booked: frappe.throw(_("Please set Number of Depreciations Booked")) else: self.number_of_depreciations_booked = 0 - + if cint(self.number_of_depreciations_booked) > cint(self.total_number_of_depreciations): frappe.throw(_("Number of Depreciations Booked cannot be greater than Total Number of Depreciations")) - + if self.next_depreciation_date and getdate(self.next_depreciation_date) < getdate(nowdate()): frappe.msgprint(_("Next Depreciation Date is entered as past date"), title=_('Warning'), indicator='red') - + if self.next_depreciation_date and getdate(self.next_depreciation_date) < getdate(self.purchase_date): frappe.throw(_("Next Depreciation Date cannot be before Purchase Date")) - - if (flt(self.value_after_depreciation) > flt(self.expected_value_after_useful_life) + + if (flt(self.value_after_depreciation) > flt(self.expected_value_after_useful_life) and not self.next_depreciation_date): frappe.throw(_("Please set Next Depreciation Date")) def make_depreciation_schedule(self): if self.depreciation_method != 'Manual': self.schedules = [] - + if not self.get("schedules") and self.next_depreciation_date: value_after_depreciation = flt(self.value_after_depreciation) - + number_of_pending_depreciations = cint(self.total_number_of_depreciations) - \ cint(self.number_of_depreciations_booked) if number_of_pending_depreciations: @@ -111,7 +111,7 @@ class Asset(Document): "schedule_date": schedule_date, "depreciation_amount": depreciation_amount }) - + def set_accumulated_depreciation(self): accumulated_depreciation = flt(self.opening_accumulated_depreciation) for d in self.get("schedules"): @@ -121,7 +121,7 @@ class Asset(Document): def get_depreciation_amount(self, depreciable_value): if self.depreciation_method in ("Straight Line", "Manual"): depreciation_amount = (flt(self.value_after_depreciation) - - flt(self.expected_value_after_useful_life)) / (cint(self.total_number_of_depreciations) - + flt(self.expected_value_after_useful_life)) / (cint(self.total_number_of_depreciations) - cint(self.number_of_depreciations_booked)) else: factor = 200.0 / self.total_number_of_depreciations @@ -132,14 +132,14 @@ class Asset(Document): depreciation_amount = flt(depreciable_value) - flt(self.expected_value_after_useful_life) return depreciation_amount - + def validate_expected_value_after_useful_life(self): accumulated_depreciation_after_full_schedule = \ max([d.accumulated_depreciation_amount for d in self.get("schedules")]) - - asset_value_after_full_schedule = (flt(self.gross_purchase_amount) - + + asset_value_after_full_schedule = (flt(self.gross_purchase_amount) - flt(accumulated_depreciation_after_full_schedule)) - + if self.expected_value_after_useful_life < asset_value_after_full_schedule: frappe.throw(_("Expected value after useful life must be greater than or equal to {0}") .format(asset_value_after_full_schedule)) @@ -156,8 +156,8 @@ class Asset(Document): if d.journal_entry: frappe.get_doc("Journal Entry", d.journal_entry).cancel() d.db_set("journal_entry", None) - - self.db_set("value_after_depreciation", + + self.db_set("value_after_depreciation", (flt(self.gross_purchase_amount) - flt(self.opening_accumulated_depreciation))) def set_status(self, status=None): @@ -188,6 +188,7 @@ def make_purchase_invoice(asset, item_code, gross_purchase_amount, company, post pi = frappe.new_doc("Purchase Invoice") pi.company = company pi.currency = frappe.db.get_value("Company", company, "default_currency") + pi.set_posting_date = 1 pi.posting_date = posting_date pi.append("items", { "item_code": item_code, @@ -200,7 +201,7 @@ def make_purchase_invoice(asset, item_code, gross_purchase_amount, company, post }) pi.set_missing_values() return pi - + @frappe.whitelist() def make_sales_invoice(asset, item_code, company): si = frappe.new_doc("Sales Invoice") @@ -217,7 +218,7 @@ def make_sales_invoice(asset, item_code, company): }) si.set_missing_values() return si - + @frappe.whitelist() def transfer_asset(args): import json @@ -226,23 +227,23 @@ def transfer_asset(args): movement_entry.update(args) movement_entry.insert() movement_entry.submit() - + frappe.db.commit() - + frappe.msgprint(_("Asset Movement record {0} created").format("{0}".format(movement_entry.name))) - + @frappe.whitelist() def get_item_details(item_code): asset_category = frappe.db.get_value("Item", item_code, "asset_category") - + if not asset_category: frappe.throw(_("Please enter Asset Category in Item {0}").format(item_code)) - - ret = frappe.db.get_value("Asset Category", asset_category, + + ret = frappe.db.get_value("Asset Category", asset_category, ["depreciation_method", "total_number_of_depreciations", "frequency_of_depreciation"], as_dict=1) - + ret.update({ "asset_category": asset_category }) - + return ret diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.json b/erpnext/accounts/doctype/payment_entry/payment_entry.json index e744a3cf356..7fac377c026 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.json +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_guest_to_view": 0, "allow_import": 1, "allow_rename": 0, "autoname": "naming_series:", @@ -254,7 +255,7 @@ "collapsible": 0, "columns": 0, "default": "", - "depends_on": "eval:in_list([\"Receive\", \"Pay\"], doc.payment_type)", + "depends_on": "eval:in_list([\"Receive\", \"Pay\"], doc.payment_type) && doc.docstatus==0", "fieldname": "party_type", "fieldtype": "Link", "hidden": 0, @@ -1664,17 +1665,17 @@ "unique": 0 } ], + "has_web_view": 0, "hide_heading": 0, "hide_toolbar": 0, "idx": 0, "image_view": 0, "in_create": 0, - "in_dialog": 0, "is_submittable": 1, "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2017-02-17 16:15:52.917533", + "modified": "2017-03-14 17:12:48.816644", "modified_by": "Administrator", "module": "Accounts", "name": "Payment Entry", diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index f3d311b56d9..cb4a0875aeb 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -1046,6 +1046,8 @@ class TestSalesInvoice(unittest.TestCase): def create_sales_invoice(**args): si = frappe.new_doc("Sales Invoice") args = frappe._dict(args) + if si.posting_date: + si.set_posting_date = 1 si.posting_date = args.posting_date or nowdate() si.company = args.company or "_Test Company" diff --git a/erpnext/controllers/recurring_document.py b/erpnext/controllers/recurring_document.py index a0367608d26..713e9bac2f1 100644 --- a/erpnext/controllers/recurring_document.py +++ b/erpnext/controllers/recurring_document.py @@ -93,6 +93,9 @@ def make_new_document(reference_doc, date_field, posting_date): "next_date": get_next_date(reference_doc.next_date, mcount,cint(reference_doc.repeat_on_day_of_month)) }) + if new_document.meta.get_field('set_posting_time'): + new_document.set('set_posting_time', 1) + # copy document fields for fieldname in ("owner", "recurring_type", "repeat_on_day_of_month", "recurring_id", "notification_email_address", "is_recurring", "end_date", diff --git a/erpnext/stock/doctype/delivery_note/test_delivery_note.py b/erpnext/stock/doctype/delivery_note/test_delivery_note.py index f10b981d73c..fce11dce51e 100644 --- a/erpnext/stock/doctype/delivery_note/test_delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/test_delivery_note.py @@ -328,7 +328,7 @@ class TestDeliveryNote(unittest.TestCase): def test_delivery_of_bundled_items_to_target_warehouse(self): set_perpetual_inventory() - + set_valuation_method("_Test Item", "FIFO") set_valuation_method("_Test Item Home Desktop 100", "FIFO") @@ -337,7 +337,7 @@ class TestDeliveryNote(unittest.TestCase): qty=100, rate=100) create_stock_reconciliation(item_code="_Test Item Home Desktop 100", target=warehouse, qty=100, rate=100) - + opening_qty_test_warehouse_1 = get_qty_after_transaction(warehouse="_Test Warehouse 1 - _TC") dn = create_delivery_note(item_code="_Test Product Bundle Item", @@ -354,28 +354,28 @@ class TestDeliveryNote(unittest.TestCase): # stock value diff for source warehouse # for "_Test Item" - stock_value_difference = frappe.db.get_value("Stock Ledger Entry", - {"voucher_type": "Delivery Note", "voucher_no": dn.name, + stock_value_difference = frappe.db.get_value("Stock Ledger Entry", + {"voucher_type": "Delivery Note", "voucher_no": dn.name, "item_code": "_Test Item", "warehouse": "_Test Warehouse - _TC"}, "stock_value_difference") # stock value diff for target warehouse - stock_value_difference1 = frappe.db.get_value("Stock Ledger Entry", - {"voucher_type": "Delivery Note", "voucher_no": dn.name, + stock_value_difference1 = frappe.db.get_value("Stock Ledger Entry", + {"voucher_type": "Delivery Note", "voucher_no": dn.name, "item_code": "_Test Item", "warehouse": "_Test Warehouse 1 - _TC"}, "stock_value_difference") self.assertEquals(abs(stock_value_difference), stock_value_difference1) # for "_Test Item Home Desktop 100" - stock_value_difference = frappe.db.get_value("Stock Ledger Entry", - {"voucher_type": "Delivery Note", "voucher_no": dn.name, + stock_value_difference = frappe.db.get_value("Stock Ledger Entry", + {"voucher_type": "Delivery Note", "voucher_no": dn.name, "item_code": "_Test Item Home Desktop 100", "warehouse": "_Test Warehouse - _TC"}, "stock_value_difference") # stock value diff for target warehouse - stock_value_difference1 = frappe.db.get_value("Stock Ledger Entry", - {"voucher_type": "Delivery Note", "voucher_no": dn.name, + stock_value_difference1 = frappe.db.get_value("Stock Ledger Entry", + {"voucher_type": "Delivery Note", "voucher_no": dn.name, "item_code": "_Test Item Home Desktop 100", "warehouse": "_Test Warehouse 1 - _TC"}, "stock_value_difference") @@ -397,118 +397,120 @@ class TestDeliveryNote(unittest.TestCase): self.assertEquals([gle.debit, gle.credit], expected_values.get(gle.account)) set_perpetual_inventory(0) - + def test_closed_delivery_note(self): from erpnext.stock.doctype.delivery_note.delivery_note import update_delivery_note_status - + dn = create_delivery_note(do_not_submit=True) dn.submit() - + update_delivery_note_status(dn.name, "Closed") self.assertEquals(frappe.db.get_value("Delivery Note", dn.name, "Status"), "Closed") - + def test_dn_billing_status_case1(self): # SO -> DN -> SI so = make_sales_order() dn = create_dn_against_so(so.name, delivered_qty=2) - + self.assertEqual(dn.status, "To Bill") self.assertEqual(dn.per_billed, 0) - + si = make_sales_invoice(dn.name) si.submit() - + dn.load_from_db() self.assertEqual(dn.get("items")[0].billed_amt, 200) self.assertEqual(dn.per_billed, 100) self.assertEqual(dn.status, "Completed") - + def test_dn_billing_status_case2(self): # SO -> SI and SO -> DN1, DN2 from erpnext.selling.doctype.sales_order.sales_order import make_delivery_note, make_sales_invoice - + so = make_sales_order() - + si = make_sales_invoice(so.name) si.get("items")[0].qty = 5 si.insert() si.submit() - + frappe.db.set_value("Stock Settings", None, "allow_negative_stock", 1) - + dn1 = make_delivery_note(so.name) + dn1.set_posting_time = 1 dn1.posting_time = "10:00" dn1.get("items")[0].qty = 2 dn1.submit() - + self.assertEqual(dn1.get("items")[0].billed_amt, 200) self.assertEqual(dn1.per_billed, 100) self.assertEqual(dn1.status, "Completed") - + dn2 = make_delivery_note(so.name) dn2.posting_time = "08:00" dn2.get("items")[0].qty = 4 dn2.submit() - + dn1.load_from_db() self.assertEqual(dn1.get("items")[0].billed_amt, 100) self.assertEqual(dn1.per_billed, 50) self.assertEqual(dn1.status, "To Bill") - + self.assertEqual(dn2.get("items")[0].billed_amt, 400) self.assertEqual(dn2.per_billed, 100) self.assertEqual(dn2.status, "Completed") - + def test_dn_billing_status_case3(self): # SO -> DN1 -> SI and SO -> SI and SO -> DN2 from erpnext.selling.doctype.sales_order.sales_order \ import make_delivery_note, make_sales_invoice as make_sales_invoice_from_so frappe.db.set_value("Stock Settings", None, "allow_negative_stock", 1) - + so = make_sales_order() - + dn1 = make_delivery_note(so.name) + dn1.set_posting_time = 1 dn1.posting_time = "10:00" dn1.get("items")[0].qty = 2 dn1.submit() si1 = make_sales_invoice(dn1.name) si1.submit() - + dn1.load_from_db() self.assertEqual(dn1.per_billed, 100) - + si2 = make_sales_invoice_from_so(so.name) si2.get("items")[0].qty = 4 si2.submit() - + dn2 = make_delivery_note(so.name) dn2.posting_time = "08:00" dn2.get("items")[0].qty = 5 dn2.submit() - + dn1.load_from_db() self.assertEqual(dn1.get("items")[0].billed_amt, 200) self.assertEqual(dn1.per_billed, 100) self.assertEqual(dn1.status, "Completed") - + self.assertEqual(dn2.get("items")[0].billed_amt, 400) self.assertEqual(dn2.per_billed, 80) self.assertEqual(dn2.status, "To Bill") - + def test_dn_billing_status_case4(self): # SO -> SI -> DN from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_delivery_note - + so = make_sales_order() - + si = make_sales_invoice(so.name) si.submit() - + dn = make_delivery_note(si.name) dn.submit() - + self.assertEqual(dn.get("items")[0].billed_amt, 1000) self.assertEqual(dn.per_billed, 100) self.assertEqual(dn.status, "Completed") diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py index 30f2a061527..79df591349a 100644 --- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py @@ -79,10 +79,10 @@ class TestStockEntry(unittest.TestCase): def test_auto_material_request_for_variant(self): self._test_auto_material_request("_Test Variant Item-S") - + def test_auto_material_request_for_warehouse_group(self): self._test_auto_material_request("_Test Item Warehouse Group Wise Reorder", warehouse="_Test Warehouse Group-C1 - _TC") - + def _test_auto_material_request(self, item_code, material_request_type="Purchase", warehouse="_Test Warehouse - _TC"): item = frappe.get_doc("Item", item_code) @@ -126,7 +126,7 @@ class TestStockEntry(unittest.TestCase): mr = make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, basic_rate=100, expense_account="Stock Adjustment - _TC") - + stock_in_hand_account = frappe.db.get_value("Account", {"account_type": "Stock", "warehouse": mr.get("items")[0].t_warehouse}) @@ -154,7 +154,7 @@ class TestStockEntry(unittest.TestCase): make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, basic_rate=100, expense_account="Stock Adjustment - _TC") - mi = make_stock_entry(item_code="_Test Item", source="_Test Warehouse - _TC", + mi = make_stock_entry(item_code="_Test Item", source="_Test Warehouse - _TC", qty=40, expense_account="Stock Adjustment - _TC") self.check_stock_ledger_entries("Stock Entry", mi.name, @@ -512,6 +512,7 @@ class TestStockEntry(unittest.TestCase): # test freeze_stocks_upto_days frappe.db.set_value("Stock Settings", None, "stock_frozen_upto_days", 7) se = frappe.copy_doc(test_records[0]) + se.set_posting_time = 1 se.posting_date = add_days(nowdate(), -15) se.insert() self.assertRaises(StockFreezeError, se.submit) diff --git a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py index f9629a1ff22..212bb51185d 100644 --- a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py @@ -37,7 +37,7 @@ class TestStockReconciliation(unittest.TestCase): for d in input_data: set_valuation_method("_Test Item", valuation_method) - + last_sle = get_previous_sle({ "item_code": "_Test Item", "warehouse": "_Test Warehouse - _TC", @@ -96,6 +96,7 @@ def create_stock_reconciliation(**args): sr = frappe.new_doc("Stock Reconciliation") sr.posting_date = args.posting_date or nowdate() sr.posting_time = args.posting_time or nowtime() + sr.set_posting_time = 1 sr.company = args.company or "_Test Company" sr.expense_account = args.expense_account or \ ("Stock Adjustment - _TC" if frappe.get_all("Stock Ledger Entry") else "Temporary Opening - _TC") From 131866a11acd5c87295bea289b08970dea33cced Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 14 Mar 2017 21:06:15 +0530 Subject: [PATCH 5/6] [fixes] for tests --- erpnext/accounts/doctype/asset/asset.py | 2 +- erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py | 2 +- erpnext/stock/doctype/stock_entry/stock_entry_utils.py | 3 +++ erpnext/utilities/transaction_base.py | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/doctype/asset/asset.py b/erpnext/accounts/doctype/asset/asset.py index a99a8cff063..f9a3b2fcf09 100644 --- a/erpnext/accounts/doctype/asset/asset.py +++ b/erpnext/accounts/doctype/asset/asset.py @@ -188,7 +188,7 @@ def make_purchase_invoice(asset, item_code, gross_purchase_amount, company, post pi = frappe.new_doc("Purchase Invoice") pi.company = company pi.currency = frappe.db.get_value("Company", company, "default_currency") - pi.set_posting_date = 1 + pi.set_posting_time = 1 pi.posting_date = posting_date pi.append("items", { "item_code": item_code, diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index cb4a0875aeb..9a1af7f9232 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -1046,7 +1046,7 @@ class TestSalesInvoice(unittest.TestCase): def create_sales_invoice(**args): si = frappe.new_doc("Sales Invoice") args = frappe._dict(args) - if si.posting_date: + if args.posting_date: si.set_posting_date = 1 si.posting_date = args.posting_date or nowdate() diff --git a/erpnext/stock/doctype/stock_entry/stock_entry_utils.py b/erpnext/stock/doctype/stock_entry/stock_entry_utils.py index cb3bb7bc5e6..e58042d75ce 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry_utils.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry_utils.py @@ -9,6 +9,9 @@ def make_stock_entry(**args): s = frappe.new_doc("Stock Entry") args = frappe._dict(args) + if args.posting_date or args.posting_time: + s.set_posting_time = 1 + if args.posting_date: s.posting_date = args.posting_date if args.posting_time: diff --git a/erpnext/utilities/transaction_base.py b/erpnext/utilities/transaction_base.py index d447482956e..688d6c4ec0e 100644 --- a/erpnext/utilities/transaction_base.py +++ b/erpnext/utilities/transaction_base.py @@ -18,7 +18,7 @@ class TransactionBase(StatusUpdater): frappe.db.get_value("Notification Control", None, dt + "_message")) def validate_posting_time(self): - if not getattr(self, 'set_posting_time', False): + if not getattr(self, 'set_posting_time', None): now = now_datetime() self.posting_date = now.strftime('%Y-%m-%d') self.posting_time = now.strftime('%H:%M:%S') From 4f3da42b750c0d9c1d9e73bec3fe228e6135c0ff Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 14 Mar 2017 21:29:55 +0530 Subject: [PATCH 6/6] [fixes] for tests --- erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py | 2 +- erpnext/stock/doctype/delivery_note/test_delivery_note.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index 9a1af7f9232..305b689e15b 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -1047,7 +1047,7 @@ def create_sales_invoice(**args): si = frappe.new_doc("Sales Invoice") args = frappe._dict(args) if args.posting_date: - si.set_posting_date = 1 + si.set_posting_time = 1 si.posting_date = args.posting_date or nowdate() si.company = args.company or "_Test Company" diff --git a/erpnext/stock/doctype/delivery_note/test_delivery_note.py b/erpnext/stock/doctype/delivery_note/test_delivery_note.py index fce11dce51e..fdb6ac93bd0 100644 --- a/erpnext/stock/doctype/delivery_note/test_delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/test_delivery_note.py @@ -447,6 +447,7 @@ class TestDeliveryNote(unittest.TestCase): self.assertEqual(dn1.status, "Completed") dn2 = make_delivery_note(so.name) + dn2.set_posting_time = 1 dn2.posting_time = "08:00" dn2.get("items")[0].qty = 4 dn2.submit()