Merge branch 'develop'
diff --git a/.travis.yml b/.travis.yml
index 31f4408..9cad59f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,4 +1,5 @@
language: python
+dist: trusty
python:
- "2.7"
@@ -11,10 +12,14 @@
- "sh -e /etc/init.d/xvfb start"
install:
- - sudo apt-get purge -y mysql-common
- - wget https://raw.githubusercontent.com/frappe/bench/master/install_scripts/setup_frappe.sh
- - sudo bash setup_frappe.sh --skip-setup-bench --mysql-root-password travis --bench-branch develop
- - sudo pip install --upgrade pip
+ - sudo apt-get purge -y mysql-common mysql-server mysql-client
+ # - wget https://raw.githubusercontent.com/frappe/bench/master/install_scripts/setup_frappe.sh
+ # - sudo bash setup_frappe.sh --skip-setup-bench --mysql-root-password travis --bench-branch develop
+ - wget https://raw.githubusercontent.com/frappe/bench/master/playbooks/install.py
+ - sudo python install.py --develop --user travis --without-bench-setup
+ - sudo pip install -e ~/bench
+
+ # - sudo pip install --upgrade pip
- rm $TRAVIS_BUILD_DIR/.git/shallow
- bash $TRAVIS_BUILD_DIR/travis/bench_init.sh
- cp -r $TRAVIS_BUILD_DIR/test_sites/test_site ~/frappe-bench/sites/
@@ -30,7 +35,7 @@
- bench --verbose run-tests --driver Firefox
before_script:
- - mysql -e 'create database test_frappe'
+ - mysql -u root -ptravis -e 'create database test_frappe'
- echo "USE mysql;\nCREATE USER 'test_frappe'@'localhost' IDENTIFIED BY 'test_frappe';\nFLUSH PRIVILEGES;\n" | mysql -u root -ptravis
- echo "USE mysql;\nGRANT ALL PRIVILEGES ON \`test_frappe\`.* TO 'test_frappe'@'localhost';\n" | mysql -u root -ptravis
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index d6310b8..11232b3 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -2,7 +2,7 @@
from __future__ import unicode_literals
import frappe
-__version__ = '7.0.16'
+__version__ = '7.0.17'
def get_default_company(user=None):
'''Get default company for user'''
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index 6c04cf5..175ebda 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -569,10 +569,9 @@
@frappe.whitelist()
def get_reference_details(reference_doctype, reference_name, party_account_currency):
total_amount = outstanding_amount = exchange_rate = None
+ ref_doc = frappe.get_doc(reference_doctype, reference_name)
if reference_doctype != "Journal Entry":
- ref_doc = frappe.get_doc(reference_doctype, reference_name)
-
if party_account_currency == ref_doc.company_currency:
total_amount = ref_doc.base_grand_total
exchange_rate = 1
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index b284619..f055140 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -87,15 +87,6 @@
def before_save(self):
set_account_for_mode_of_payment(self)
- def update_change_amount(self):
- self.base_paid_amount = 0.0
- if self.paid_amount:
- self.base_paid_amount = flt(self.paid_amount * self.conversion_rate, self.precision("base_paid_amount"))
- self.change_amount = self.base_change_amount = 0.0
- if self.paid_amount > self.grand_total:
- self.change_amount = flt(self.paid_amount - self.grand_total, self.precision("change_amount"))
- self.base_change_amount = flt(self.change_amount * self.conversion_rate, self.precision("base_change_amount"))
-
def on_submit(self):
if not self.recurring_id:
frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype,
@@ -110,6 +101,7 @@
self.update_status_updater_args()
self.update_prevdoc_status()
self.update_billing_status_in_dn()
+ self.clear_unallocated_mode_of_payments()
# Updating stock ledger should always be called after updating prevdoc status,
# because updating reserved qty in bin depends upon updated delivered qty in SO
@@ -296,6 +288,12 @@
frappe.throw(_("Debit To account must be a Receivable account"))
self.party_account_currency = account.account_currency
+
+ def clear_unallocated_mode_of_payments(self):
+ self.set("payments", self.get("payments", {"amount": ["not in", [0, None, ""]]}))
+
+ frappe.db.sql("""delete from `tabSales Invoice Payment` where parent = %s
+ and amount = 0""", self.name)
def validate_with_previous_doc(self):
super(SalesInvoice, self).validate_with_previous_doc({
@@ -504,6 +502,7 @@
gl_entries = merge_similar_entries(gl_entries)
self.make_pos_gl_entries(gl_entries)
+ self.make_gle_for_change(gl_entries)
self.make_write_off_gl_entry(gl_entries)
@@ -578,27 +577,24 @@
def make_pos_gl_entries(self, gl_entries):
if cint(self.is_pos) and self.paid_amount:
- # POS, make payment entries
- gl_entries.append(
- self.get_gl_dict({
- "account": self.debit_to,
- "party_type": "Customer",
- "party": self.customer,
- "against": self.cash_bank_account,
- "credit": flt(self.base_paid_amount - self.base_change_amount),
- "credit_in_account_currency": flt(self.base_paid_amount - self.base_change_amount) \
- if self.party_account_currency==self.company_currency else flt(self.paid_amount - self.change_amount),
- "against_voucher": self.return_against if cint(self.is_return) else self.name,
- "against_voucher_type": self.doctype,
- }, self.party_account_currency)
- )
-
- cash_account = ''
for payment_mode in self.payments:
- if payment_mode.type == 'Cash':
- cash_account = payment_mode.account
-
if payment_mode.base_amount > 0:
+ # POS, make payment entries
+ gl_entries.append(
+ self.get_gl_dict({
+ "account": self.debit_to,
+ "party_type": "Customer",
+ "party": self.customer,
+ "against": payment_mode.account,
+ "credit": payment_mode.base_amount,
+ "credit_in_account_currency": payment_mode.base_amount \
+ if self.party_account_currency==self.company_currency \
+ else payment_mode.amount,
+ "against_voucher": self.return_against if cint(self.is_return) else self.name,
+ "against_voucher_type": self.doctype,
+ }, self.party_account_currency)
+ )
+
payment_mode_account_currency = get_account_currency(payment_mode.account)
gl_entries.append(
self.get_gl_dict({
@@ -609,20 +605,44 @@
if payment_mode_account_currency==self.company_currency else payment_mode.amount
}, payment_mode_account_currency)
)
-
- if self.change_amount:
- cash_account = cash_account or self.payments[0].account
- cash_account_currency = get_account_currency(cash_account)
+
+ def make_gle_for_change(self, gl_entries):
+ if cint(self.is_pos) and self.change_amount:
+ cash_account = self.get_cash_account()
+ if cash_account:
+ gl_entries.append(
+ self.get_gl_dict({
+ "account": self.debit_to,
+ "party_type": "Customer",
+ "party": self.customer,
+ "against": cash_account,
+ "debit": flt(self.base_change_amount),
+ "debit_in_account_currency": flt(self.base_change_amount) \
+ if self.party_account_currency==self.company_currency else flt(self.change_amount),
+ "against_voucher": self.return_against if cint(self.is_return) else self.name,
+ "against_voucher_type": self.doctype
+ }, self.party_account_currency)
+ )
+
gl_entries.append(
self.get_gl_dict({
"account": cash_account,
"against": self.customer,
- "credit": self.base_change_amount,
- "credit_in_account_currency": self.base_change_amount \
- if payment_mode_account_currency==self.company_currency else self.change_amount
- }, payment_mode_account_currency)
+ "credit": self.base_change_amount
+ })
)
-
+
+
+ def get_cash_account(self):
+ cash_account = [d.account for d in self.payments if d.type=="Cash"]
+ if cash_account:
+ cash_account = cash_account[0]
+ else:
+ cash_account = frappe.db.get_value("Account",
+ filters={"company": self.company, "account_type": "Cash", "is_group": 0})
+
+ return cash_account
+
def make_write_off_gl_entry(self, gl_entries):
# write off entries, applicable if only pos
if self.write_off_account and self.write_off_amount:
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index e7eee5f..dd28059 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -503,7 +503,8 @@
[pos["taxes"][1]["account_head"], 0.0, 50.0],
[stock_in_hand, 0.0, abs(sle.stock_value_difference)],
[pos["items"][0]["expense_account"], abs(sle.stock_value_difference), 0.0],
- [si.debit_to, 0.0, si.paid_amount],
+ [si.debit_to, 0.0, 300.0],
+ [si.debit_to, 0.0, cash_amount],
["_Test Bank - _TC", 300.0, 0.0],
["Cash - _TC", cash_amount, 0.0]
])
diff --git a/erpnext/config/accounts.py b/erpnext/config/accounts.py
index a0fcb63..419d83f 100644
--- a/erpnext/config/accounts.py
+++ b/erpnext/config/accounts.py
@@ -27,6 +27,12 @@
"description": _("Bank/Cash transactions against party or for internal transfer")
},
{
+ "type": "page",
+ "name": "pos",
+ "label": _("POS"),
+ "description": _("Point of Sale")
+ },
+ {
"type": "report",
"name": "Accounts Receivable",
"doctype": "Sales Invoice",
diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py
index eb75dee..28b2f7c 100644
--- a/erpnext/controllers/taxes_and_totals.py
+++ b/erpnext/controllers/taxes_and_totals.py
@@ -440,33 +440,32 @@
paid_amount = self.doc.paid_amount \
if self.doc.party_account_currency == self.doc.currency else self.doc.base_paid_amount
- self.doc.outstanding_amount = 0
- if total_amount_to_pay > paid_amount:
- self.doc.outstanding_amount = flt(total_amount_to_pay - flt(paid_amount),
- self.doc.precision("outstanding_amount"))
- self.change_amount()
+ self.calculate_change_amount()
+ self.doc.outstanding_amount = flt(total_amount_to_pay - flt(paid_amount) +
+ flt(self.doc.change_amount), self.doc.precision("outstanding_amount"))
+
elif self.doc.doctype == "Purchase Invoice":
self.doc.outstanding_amount = flt(total_amount_to_pay, self.doc.precision("outstanding_amount"))
def calculate_paid_amount(self):
paid_amount = base_paid_amount = 0.0
for payment in self.doc.get('payments'):
- payment.base_amount = flt(payment.amount * self.doc.conversion_rate)
- paid_amount += payment.amount
- base_paid_amount += payment.base_amount
+ if flt(payment.amount) > 0:
+ payment.base_amount = flt(payment.amount * self.doc.conversion_rate)
+ paid_amount += payment.amount
+ base_paid_amount += payment.base_amount
self.doc.paid_amount = flt(paid_amount, self.doc.precision("paid_amount"))
self.doc.base_paid_amount = flt(base_paid_amount, self.doc.precision("base_paid_amount"))
- def change_amount(self):
- change_amount = 0.0
+ def calculate_change_amount(self):
+ self.doc.change_amount = 0.0
if self.doc.paid_amount > self.doc.grand_total:
- change_amount = flt(self.doc.paid_amount - self.doc.grand_total,
- self.doc.precision("change_amount"))
+ self.doc.change_amount = flt(self.doc.paid_amount - self.doc.grand_total +
+ self.doc.write_off_amount, self.doc.precision("change_amount"))
- self.doc.change_amount = change_amount;
- self.doc.base_change_amount = flt(change_amount * self.doc.conversion_rate,
+ self.doc.base_change_amount = flt(self.doc.change_amount * self.doc.conversion_rate,
self.doc.precision("base_change_amount"))
def calculate_margin(self, item):
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py
index 2b173bf..0f6dae6 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/production_order.py
@@ -540,7 +540,7 @@
po = frappe.get_doc('Production Order', source_name)
ts = po.make_time_logs(open_new=True)
- if not ts.get('time_logs'):
+ if not ts or not ts.get('time_logs'):
frappe.throw(_("Already completed"))
return ts
diff --git a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py
index 4770781..5fbcf1e 100644
--- a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py
+++ b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py
@@ -451,10 +451,8 @@
"company": self.company,
"requested_by": frappe.session.user
})
- if item_wrapper.default_bom:
- material_request.update({"material_request_type": "Manufacture"})
- else:
- material_request.update({"material_request_type": "Purchase"})
+ material_request.update({"material_request_type": item_wrapper.default_material_request_type})
+
for sales_order, requested_qty in items_to_be_requested[item].items():
material_request.append("items", {
"doctype": "Material Request Item",
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 97f5bd5..4d3932f 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -306,4 +306,5 @@
erpnext.patches.v7_0.fix_nonwarehouse_ledger_gl_entries_for_transactions
erpnext.patches.v7_0.remove_old_earning_deduction_doctypes
erpnext.patches.v7_0.make_guardian
-erpnext.patches.v7_0.update_refdoc_in_landed_cost_voucher
\ No newline at end of file
+erpnext.patches.v7_0.update_refdoc_in_landed_cost_voucher
+execute:frappe.db.sql("update `tabItem` set default_material_request_type= case when default_bom is not null then 'Manufacture' else 'Purchase' end")
diff --git a/erpnext/patches/v7_0/make_guardian.py b/erpnext/patches/v7_0/make_guardian.py
index 15b9bd1..f654b79 100644
--- a/erpnext/patches/v7_0/make_guardian.py
+++ b/erpnext/patches/v7_0/make_guardian.py
@@ -6,6 +6,7 @@
frappe.reload_doc("schools", "doctype", "student")
frappe.reload_doc("schools", "doctype", "guardian")
frappe.reload_doc("schools", "doctype", "guardian_interest")
+ frappe.reload_doc("hr", "doctype", "interest")
students = frappe.get_all("Student", fields=["name", "father_name", "father_email_id",
"mother_name", "mother_email_id"])
diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js
index 34c4557..576bc71 100644
--- a/erpnext/public/js/controllers/taxes_and_totals.js
+++ b/erpnext/public/js/controllers/taxes_and_totals.js
@@ -561,22 +561,18 @@
this.calculate_paid_amount()
}
+ this.calculate_change_amount()
var outstanding_amount = 0.0
var paid_amount = (this.frm.doc.party_account_currency == this.frm.doc.currency) ?
this.frm.doc.paid_amount : this.frm.doc.base_paid_amount;
- if (total_amount_to_pay > paid_amount){
- outstanding_amount = flt(total_amount_to_pay - flt(paid_amount),
- precision("outstanding_amount"));
- }
+ this.frm.doc.outstanding_amount = flt(total_amount_to_pay - flt(paid_amount) +
+ flt(this.frm.doc.change_amount), precision("outstanding_amount"));
} else if(this.frm.doc.doctype == "Purchase Invoice") {
- var outstanding_amount = flt(total_amount_to_pay, precision("outstanding_amount"));
- }
-
- this.frm.doc.outstanding_amount = outstanding_amount;
- this.calculate_change_amount()
+ this.frm.doc.outstanding_amount = flt(total_amount_to_pay, precision("outstanding_amount"));
+ }
},
set_default_payment: function(total_amount_to_pay, update_paid_amount){
@@ -610,15 +606,13 @@
},
calculate_change_amount: function(){
- var change_amount = 0.0;
+ this.frm.doc.change_amount = 0.0;
if(this.frm.doc.paid_amount > this.frm.doc.grand_total){
- change_amount = flt(this.frm.doc.paid_amount - this.frm.doc.grand_total,
- precision("change_amount"))
+ this.frm.doc.change_amount = flt(this.frm.doc.paid_amount - this.frm.doc.grand_total +
+ this.frm.doc.write_off_amount, precision("change_amount"));
}
- this.frm.doc.change_amount = flt(change_amount,
- precision("change_amount"))
- this.frm.doc.base_change_amount = flt(change_amount * this.frm.doc.conversion_rate,
- precision("base_change_amount"))
+ this.frm.doc.base_change_amount = flt(this.frm.doc.change_amount * this.frm.doc.conversion_rate,
+ precision("base_change_amount"));
},
})
diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js
index 17e379c..1f793d1 100644
--- a/erpnext/stock/doctype/item/item.js
+++ b/erpnext/stock/doctype/item/item.js
@@ -116,6 +116,14 @@
}
});
+frappe.ui.form.on('Item Reorder', {
+ reorder_levels_add: function(frm, cdt, cdn) {
+ var row = frappe.get_doc(cdt, cdn);
+ type = frm.doc.default_material_request_type
+ row.material_request_type = (type == 'Material Transfer')? 'Transfer' : type;
+ }
+})
+
$.extend(erpnext.item, {
setup_queries: function(frm) {
frm.fields_dict['expense_account'].get_query = function(doc) {
@@ -351,6 +359,7 @@
}
});
+
cur_frm.add_fetch('attribute', 'numeric_values', 'numeric_values');
cur_frm.add_fetch('attribute', 'from_range', 'from_range');
cur_frm.add_fetch('attribute', 'to_range', 'to_range');
diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json
index e2aa274..ab3f601 100644
--- a/erpnext/stock/doctype/item/item.json
+++ b/erpnext/stock/doctype/item/item.json
@@ -709,6 +709,33 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "default": "Purchase",
+ "fieldname": "default_material_request_type",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Default Material Request Type",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Purchase\nMaterial Transfer\nMaterial Issue\nManufacture",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
"depends_on": "is_stock_item",
"fieldname": "column_break1",
"fieldtype": "Column Break",
@@ -2308,7 +2335,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 1,
- "modified": "2016-07-21 18:44:10.230372",
+ "modified": "2016-07-28 19:12:27.253074",
"modified_by": "Administrator",
"module": "Stock",
"name": "Item",
diff --git a/erpnext/stock/doctype/item_reorder/item_reorder.json b/erpnext/stock/doctype/item_reorder/item_reorder.json
index 4c98c3f..43eb98d 100644
--- a/erpnext/stock/doctype/item_reorder/item_reorder.json
+++ b/erpnext/stock/doctype/item_reorder/item_reorder.json
@@ -124,8 +124,9 @@
"label": "Material Request Type",
"length": 0,
"no_copy": 0,
- "options": "Purchase\nTransfer",
+ "options": "Purchase\nTransfer\nMaterial Issue\nManufacture",
"permlevel": 0,
+ "precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
@@ -146,7 +147,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2016-07-11 03:59:06.870780",
+ "modified": "2016-07-28 19:15:38.270046",
"modified_by": "Administrator",
"module": "Stock",
"name": "Item Reorder",
diff --git a/erpnext/stock/reorder_item.py b/erpnext/stock/reorder_item.py
index ad810a9..5131381 100644
--- a/erpnext/stock/reorder_item.py
+++ b/erpnext/stock/reorder_item.py
@@ -16,7 +16,7 @@
return _reorder_item()
def _reorder_item():
- material_requests = {"Purchase": {}, "Transfer": {}}
+ material_requests = {"Purchase": {}, "Transfer": {}, "Material Issue": {}, "Manufacture": {}}
warehouse_company = frappe._dict(frappe.db.sql("""select name, company from `tabWarehouse`
where disabled=0"""))
default_company = (erpnext.get_default_company() or