diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 7c5133aff8e..6b59a1891b7 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals import frappe -__version__ = '7.0.31' +__version__ = '7.0.32' def get_default_company(user=None): '''Get default company for user''' diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 871a1512e05..35df29955d5 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -381,8 +381,10 @@ class SalesInvoice(SellingController): if d.delivery_note: msgprint(_("Stock cannot be updated against Delivery Note {0}").format(d.delivery_note), raise_exception=1) - def validate_write_off_account(self): + if flt(self.write_off_amount) and not self.write_off_account: + self.write_off_account = frappe.db.get_value('Company', self.company, 'write_off_account') + if flt(self.write_off_amount) and not self.write_off_account: msgprint(_("Please enter Write Off Account"), raise_exception=1) diff --git a/erpnext/accounts/page/pos/pos.js b/erpnext/accounts/page/pos/pos.js index 06606a97fe6..5947bde878e 100644 --- a/erpnext/accounts/page/pos/pos.js +++ b/erpnext/accounts/page/pos/pos.js @@ -509,7 +509,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ this.remove_zero_qty_item(); } - this.refresh(); + this.update_paid_amount_status(false) }, remove_zero_qty_item: function(){ @@ -591,7 +591,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ if (!caught) this.add_new_item_to_grid(); - this.refresh(); + this.update_paid_amount_status(false) }, add_new_item_to_grid: function() { @@ -616,6 +616,14 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ ? this.item_serial_no[this.child.item_code][0] : ''); }, + update_paid_amount_status: function(update_paid_amount){ + if(this.name){ + update_paid_amount = update_paid_amount ? false : true; + } + + this.refresh(update_paid_amount); + }, + refresh: function(update_paid_amount) { var me = this; this.refresh_fields(update_paid_amount); @@ -623,6 +631,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ this.update_rate(); this.set_primary_action(); }, + refresh_fields: function(update_paid_amount) { this.apply_pricing_rule(); this.discount_amount_applied = false; @@ -698,7 +707,8 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ if (this.frm.doc.docstatus==0) { this.page.set_primary_action(__("Pay"), function() { - me.validate() + me.validate(); + me.update_paid_amount_status(true); me.create_invoice(); me.make_payment(); }, "octicon octicon-credit-card"); diff --git a/erpnext/change_log/v7/v7_0_0.md b/erpnext/change_log/v7/v7_0_0.md new file mode 100644 index 00000000000..144d74dd5e6 --- /dev/null +++ b/erpnext/change_log/v7/v7_0_0.md @@ -0,0 +1,58 @@ +#### New POS +- Offline +- Multiple Payment Modes +- Standard documents cannot be edited in POS view + +#### Payment Entry +- Dedicated form for managing Payments +- Designed for normal users who do not have accounting background + +#### Request for Quotation +- Updated workflow: Material Request -> **Request for Quotation** -> Supplier Quotation -> Purchase Order + +#### Fixed Asset Management +- Manage fixed asset records and their depreciation + +#### Improved Navigation +- Heatmaps +- Centralized navigation from Masters like Item, Customer, Supplier, Employee etc. + +#### Timesheets +- New grid +- Multiple time logs in one timesheets +- Linked to Payroll and Billing + +#### Graphs in Reports +- Added graphs in some important reports like Balance Sheet, Accounts Receivable etc. + +#### Sub-warehouse +- Tree view for Warehouse + +#### New Portal Design +- New Homepage Design +- Sidebar in Portal View +- New Cart View + +#### Collaborative Project Management +- Web View +- Customers/Suppliers can add/edit issues and view timesheets + +#### Budget +- Dedicated budget form +- Budget can be assigned against Cost Center Group + +#### Check Printing Format +- Ability to customize Cheque Printing Format for any bank + +#### Schools application is now part of ERPNext + +#### Minor + +- Selling Price calculation based on Margin defined in the Pricing Rule +- Document flow-chart on Sales / Purchase Transactions +- Domain specific desktop views +- Add opening Stock and Rate while creating a new Item +- Book payments and update stock directly from Purchase Invoice +- List view for Products on Website +- Features Setup is deprecated, settings moved to individual module setup views +- Added Safety Stock to Item Master diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index fcdff21591b..3f25e0222fe 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -204,10 +204,10 @@ class StockController(AccountsController): from erpnext.stock.stock_ledger import make_sl_entries make_sl_entries(sl_entries, is_amended, allow_negative_stock, via_landed_cost_voucher) - def make_gl_entries_on_cancel(self): + def make_gl_entries_on_cancel(self, repost_future_gle=True): if frappe.db.sql("""select name from `tabGL Entry` where voucher_type=%s and voucher_no=%s""", (self.doctype, self.name)): - self.make_gl_entries() + self.make_gl_entries(repost_future_gle) def get_serialized_items(self): serialized_items = [] @@ -261,7 +261,7 @@ def update_gl_entries_after(posting_date, posting_time, for_warehouses=None, for future_stock_vouchers = get_future_stock_vouchers(posting_date, posting_time, for_warehouses, for_items) gle = get_voucherwise_gl_entries(future_stock_vouchers, posting_date) - + for voucher_type, voucher_no in future_stock_vouchers: existing_gle = gle.get((voucher_type, voucher_no), []) voucher_obj = frappe.get_doc(voucher_type, voucher_no) diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py index 125f4fedb62..da803cf75e6 100644 --- a/erpnext/controllers/taxes_and_totals.py +++ b/erpnext/controllers/taxes_and_totals.py @@ -471,7 +471,8 @@ class calculate_taxes_and_totals(object): def calculate_write_off_amount(self): if flt(self.doc.change_amount) > 0: - self.doc.write_off_amount = self.doc.grand_total - self.doc.paid_amount + self.doc.change_amount + self.doc.write_off_amount = flt(self.doc.grand_total - self.doc.paid_amount + self.doc.change_amount, + self.doc.precision("write_off_amount")) self.doc.base_write_off_amount = flt(self.doc.write_off_amount * self.doc.conversion_rate, self.doc.precision("base_write_off_amount")) diff --git a/erpnext/manufacturing/doctype/operation/operation.py b/erpnext/manufacturing/doctype/operation/operation.py index 2c75feebd44..69e83292ff8 100644 --- a/erpnext/manufacturing/doctype/operation/operation.py +++ b/erpnext/manufacturing/doctype/operation/operation.py @@ -2,13 +2,9 @@ # For license information, please see license.txt from __future__ import unicode_literals -import frappe from frappe.model.document import Document class Operation(Document): - def calculate_op_cost(self): - if self.hour_rate and self.time_in_mins: - self.operating_cost = flt(self.hour_rate) * flt(self.time_in_mins) / 60.0 - else : - self.operating_cost = 0 - + def validate(self): + if not self.description: + self.description = self.name diff --git a/erpnext/manufacturing/doctype/production_order_operation/production_order_operation.json b/erpnext/manufacturing/doctype/production_order_operation/production_order_operation.json index 3493ccf43ed..00bf934d832 100644 --- a/erpnext/manufacturing/doctype/production_order_operation/production_order_operation.json +++ b/erpnext/manufacturing/doctype/production_order_operation/production_order_operation.json @@ -58,7 +58,7 @@ "print_hide_if_no_value": 0, "read_only": 1, "report_hide": 0, - "reqd": 0, + "reqd": 1, "search_index": 0, "set_only_once": 0, "unique": 0 @@ -85,7 +85,7 @@ "print_hide_if_no_value": 0, "read_only": 1, "report_hide": 0, - "reqd": 1, + "reqd": 0, "search_index": 0, "set_only_once": 0, "unique": 0 @@ -539,7 +539,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2016-07-11 03:28:04.235889", + "modified": "2016-08-22 03:41:42.356833", "modified_by": "Administrator", "module": "Manufacturing", "name": "Production Order Operation", diff --git a/erpnext/public/js/payment/payments.js b/erpnext/public/js/payment/payments.js index 06df4252621..23db61fcb4c 100644 --- a/erpnext/public/js/payment/payments.js +++ b/erpnext/public/js/payment/payments.js @@ -112,15 +112,15 @@ erpnext.payments = erpnext.stock.StockController.extend({ $(this.$body).find('.form-control').click(function(){ me.idx = $(this).attr("idx"); me.set_outstanding_amount(); - me.update_paid_amount(); + me.update_paid_amount(true); }) $(this.$body).find('.write_off_amount').change(function(){ - me.write_off_amount(flt($(this).val())); + me.write_off_amount(flt($(this).val()), precision("write_off_amount")); }) $(this.$body).find('.change_amount').change(function(){ - me.change_amount(flt($(this).val())); + me.change_amount(flt($(this).val()), precision("change_amount")); }) }, @@ -139,7 +139,7 @@ erpnext.payments = erpnext.stock.StockController.extend({ me.payment_val += $(this).text(); me.selected_mode.val(format_number(me.payment_val, 2)) me.idx = me.selected_mode.attr("idx") - me.selected_mode.change() + me.update_paid_amount() }) $(this.$body).find('.delete-btn').click(function(){ @@ -177,31 +177,29 @@ erpnext.payments = erpnext.stock.StockController.extend({ write_off_amount: function(write_off_amount) { var me = this; - if(this.frm.doc.paid_amount > 0){ - this.frm.doc.write_off_amount = write_off_amount; - this.frm.doc.base_write_off_amount = flt(this.frm.doc.write_off_amount * this.frm.doc.conversion_rate, - precision("base_write_off_amount")); - this.calculate_outstanding_amount(false) - this.show_amounts() - } + this.frm.doc.write_off_amount = flt(write_off_amount, precision("write_off_amount")); + this.frm.doc.base_write_off_amount = flt(this.frm.doc.write_off_amount * this.frm.doc.conversion_rate, + precision("base_write_off_amount")); + this.calculate_outstanding_amount(false) + this.show_amounts() }, change_amount: function(change_amount) { var me = this; - this.frm.doc.change_amount = change_amount; + this.frm.doc.change_amount = flt(change_amount, precision("change_amount")); this.calculate_write_off_amount() this.show_amounts() }, - update_paid_amount: function() { + update_paid_amount: function(update_write_off) { var me = this; if(in_list(['change_amount', 'write_off_amount'], this.idx)){ - value = flt(me.selected_mode.val(), 2) + value = me.selected_mode.val(); if(me.idx == 'change_amount'){ me.change_amount(value) } else{ - if(value == 0) { + if(value == 0 && update_write_off) { value = me.frm.doc.outstanding_amount; } me.write_off_amount(value) @@ -226,9 +224,9 @@ erpnext.payments = erpnext.stock.StockController.extend({ show_amounts: function(){ var me = this; - $(this.$body).find(".write_off_amount").val(format_number(this.frm.doc.write_off_amount, 2)); + $(this.$body).find(".write_off_amount").val(format_number(this.frm.doc.write_off_amount, precision("write_off_amount"))); $(this.$body).find('.paid_amount').text(format_currency(this.frm.doc.paid_amount, this.frm.doc.currency)); - $(this.$body).find('.change_amount').val(format_number(this.frm.doc.change_amount, 2)) + $(this.$body).find('.change_amount').val(format_number(this.frm.doc.change_amount, precision("change_amount"))) $(this.$body).find('.outstanding_amount').text(format_currency(this.frm.doc.outstanding_amount, this.frm.doc.currency)) this.update_invoice(); } diff --git a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py index ac59e06ca87..cdf72631262 100644 --- a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py +++ b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py @@ -84,7 +84,7 @@ class LandedCostVoucher(Document): self.update_landed_cost() def update_landed_cost(self): - for d in self.get("items"): + for d in self.get("purchase_receipts"): doc = frappe.get_doc(d.receipt_document_type, d.receipt_document) # set landed cost voucher amount in pr item @@ -103,7 +103,7 @@ class LandedCostVoucher(Document): # update stock & gl entries for cancelled state of PR doc.docstatus = 2 doc.update_stock_ledger(allow_negative_stock=True, via_landed_cost_voucher=True) - doc.make_gl_entries_on_cancel() + doc.make_gl_entries_on_cancel(repost_future_gle=False) # update stock & gl entries for submit state of PR