Compare commits
128 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
97d2a00d91 | ||
|
|
1749406514 | ||
|
|
99b18224f5 | ||
|
|
b0b446e899 | ||
|
|
148386f73e | ||
|
|
1b6c3f1a39 | ||
|
|
618fefea73 | ||
|
|
31d9d9f561 | ||
|
|
e715572e7c | ||
|
|
d138b06c8e | ||
|
|
37ee57c211 | ||
|
|
95b995be6d | ||
|
|
86e479f908 | ||
|
|
2a52f59b32 | ||
|
|
c185734bf3 | ||
|
|
beb7c346ea | ||
|
|
88655890be | ||
|
|
e7b37af525 | ||
|
|
10026ea85c | ||
|
|
960118a954 | ||
|
|
8860b9d94d | ||
|
|
f4f9be9233 | ||
|
|
81bded1afe | ||
|
|
7f1d5efd5b | ||
|
|
54a10cd2af | ||
|
|
f52b5ac8af | ||
|
|
2fd33a2f03 | ||
|
|
78f137890c | ||
|
|
0d79be5628 | ||
|
|
fa555abbd2 | ||
|
|
eb00cae86c | ||
|
|
5b731ff73a | ||
|
|
5b8db3729c | ||
|
|
69fb13f229 | ||
|
|
c2acfc9828 | ||
|
|
409843d768 | ||
|
|
fb4e496b54 | ||
|
|
ff8a854b82 | ||
|
|
438b67e8b0 | ||
|
|
e440914327 | ||
|
|
dcbc4d1a46 | ||
|
|
e1637c4cae | ||
|
|
b3fb6e1e04 | ||
|
|
354443b073 | ||
|
|
d4c8dc2915 | ||
|
|
d51cf79fe2 | ||
|
|
306c49f8a0 | ||
|
|
c7cfa270cd | ||
|
|
1568dc32a2 | ||
|
|
878a18528c | ||
|
|
5fa6c4ce21 | ||
|
|
b8ad56f819 | ||
|
|
b3a142f5ab | ||
|
|
1f5b21673c | ||
|
|
093beecd0a | ||
|
|
822fd7747a | ||
|
|
f29a618b69 | ||
|
|
314af94737 | ||
|
|
6771240471 | ||
|
|
1a804e2217 | ||
|
|
ac9c2de8b9 | ||
|
|
2c6705ef83 | ||
|
|
5536923101 | ||
|
|
63e431a219 | ||
|
|
e2787cf2ec | ||
|
|
c4fa74f51d | ||
|
|
b62068f784 | ||
|
|
f8594feb55 | ||
|
|
6a0563f4b2 | ||
|
|
43539673cc | ||
|
|
4809d36fbe | ||
|
|
f61f76ba45 | ||
|
|
8d76d14614 | ||
|
|
adc830b712 | ||
|
|
ed618f284b | ||
|
|
c4d38e2183 | ||
|
|
a5c9cff38a | ||
|
|
fe8d107731 | ||
|
|
e2968e9893 | ||
|
|
fd4bcd855b | ||
|
|
2eba53f763 | ||
|
|
866e9047b0 | ||
|
|
08e04ef01a | ||
|
|
bf3f944bdb | ||
|
|
1d08304ba5 | ||
|
|
fc79e205f0 | ||
|
|
3b0adc5246 | ||
|
|
4888a5dc0d | ||
|
|
1686876b23 | ||
|
|
8c6ff9ddad | ||
|
|
3bc3384bc4 | ||
|
|
37307215d0 | ||
|
|
61704504e6 | ||
|
|
9895aba42e | ||
|
|
753e40b4d5 | ||
|
|
71b7a52990 | ||
|
|
e372fb11ea | ||
|
|
4c924bb76c | ||
|
|
de7b87ee3a | ||
|
|
f3ae85cc9a | ||
|
|
4a929d53bc | ||
|
|
7f8d6b6252 | ||
|
|
6789680fa3 | ||
|
|
4f3f5308e3 | ||
|
|
9e38d29df7 | ||
|
|
15e13c0ed4 | ||
|
|
4984bccbc6 | ||
|
|
4258753ae8 | ||
|
|
68a6d61589 | ||
|
|
c55edf18ad | ||
|
|
a60984866c | ||
|
|
555fa4fbc2 | ||
|
|
43c885868f | ||
|
|
815cb8959a | ||
|
|
38937ecd3c | ||
|
|
a27cca97b5 | ||
|
|
521aa2e94a | ||
|
|
390df6626b | ||
|
|
a2d8585b07 | ||
|
|
84e658058b | ||
|
|
10e813b010 | ||
|
|
a7bd8ee34b | ||
|
|
90a51225a4 | ||
|
|
8980ce6052 | ||
|
|
c0f56de971 | ||
|
|
8d50eb32c1 | ||
|
|
50bbc99889 | ||
|
|
0cf9469f86 |
12
.travis.yml
12
.travis.yml
@@ -6,6 +6,10 @@ python:
|
||||
services:
|
||||
- mysql
|
||||
|
||||
before_install:
|
||||
- "export DISPLAY=:99.0"
|
||||
- "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
|
||||
@@ -22,7 +26,9 @@ script:
|
||||
- bench use test_site
|
||||
- bench reinstall
|
||||
- bench build-website
|
||||
- bench --verbose run-tests
|
||||
- bench serve &
|
||||
- sleep 10
|
||||
- bench --verbose run-tests --driver Firefox
|
||||
|
||||
before_script:
|
||||
- mysql -e 'create database test_frappe'
|
||||
@@ -33,6 +39,6 @@ notifications:
|
||||
webhooks:
|
||||
urls:
|
||||
- https://webhooks.gitter.im/e/92b3bea86d8c5397beef
|
||||
on_success: always
|
||||
on_failure: always
|
||||
on_success: always
|
||||
on_failure: always
|
||||
on_start: never
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
from __future__ import unicode_literals
|
||||
__version__ = '5.0.3'
|
||||
__version__ = '5.0.12'
|
||||
|
||||
@@ -10,8 +10,8 @@ from frappe import _
|
||||
from frappe.model.document import Document
|
||||
|
||||
class GLEntry(Document):
|
||||
|
||||
def validate(self):
|
||||
self.flags.ignore_submit_comment = True
|
||||
self.check_mandatory()
|
||||
self.pl_must_have_cost_center()
|
||||
self.validate_posting_date()
|
||||
|
||||
@@ -76,9 +76,9 @@ class JournalEntry(AccountsController):
|
||||
account_type = frappe.db.get_value("Account", d.account, "account_type")
|
||||
if account_type in ["Receivable", "Payable"]:
|
||||
if not (d.party_type and d.party):
|
||||
frappe.throw(_("Row{0}: Party Type and Party is required for Receivable / Payable account {1}").format(d.idx, d.account))
|
||||
frappe.throw(_("Row {0}: Party Type and Party is required for Receivable / Payable account {1}").format(d.idx, d.account))
|
||||
elif d.party_type and d.party:
|
||||
frappe.throw(_("Row{0}: Party Type and Party is only applicable against Receivable / Payable account").format(d.idx))
|
||||
frappe.throw(_("Row {0}: Party Type and Party is only applicable against Receivable / Payable account").format(d.idx))
|
||||
|
||||
def check_credit_limit(self):
|
||||
customers = list(set([d.party for d in self.get("accounts") if d.party_type=="Customer" and flt(d.debit) > 0]))
|
||||
@@ -438,7 +438,7 @@ class JournalEntry(AccountsController):
|
||||
if self.stock_entry:
|
||||
if frappe.db.get_value("Stock Entry", self.stock_entry, "docstatus") != 1:
|
||||
frappe.throw(_("Stock Entry {0} is not submitted").format(self.stock_entry))
|
||||
|
||||
|
||||
if frappe.db.exists({"doctype": "Journal Entry", "stock_entry": self.stock_entry, "docstatus":1}):
|
||||
frappe.msgprint(_("Warning: Another {0} # {1} exists against stock entry {2}".format(self.voucher_type, self.name, self.stock_entry)))
|
||||
|
||||
|
||||
0
erpnext/accounts/doctype/pos_profile/__init__.py
Normal file
0
erpnext/accounts/doctype/pos_profile/__init__.py
Normal file
@@ -1,13 +1,13 @@
|
||||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
frappe.ui.form.on("POS Setting", "onload", function(frm) {
|
||||
frappe.ui.form.on("POS Profile", "onload", function(frm) {
|
||||
frm.set_query("selling_price_list", function() {
|
||||
return { filter: { selling: 1 } };
|
||||
});
|
||||
|
||||
frm.call({
|
||||
method: "erpnext.accounts.doctype.pos_setting.pos_setting.get_series",
|
||||
method: "erpnext.accounts.doctype.pos_profile.pos_profile.get_series",
|
||||
callback: function(r) {
|
||||
if(!r.exc) {
|
||||
set_field_options("naming_series", r.message);
|
||||
263
erpnext/accounts/doctype/pos_profile/pos_profile.json
Normal file
263
erpnext/accounts/doctype/pos_profile/pos_profile.json
Normal file
@@ -0,0 +1,263 @@
|
||||
{
|
||||
"allow_rename": 0,
|
||||
"autoname": "hash",
|
||||
"creation": "2013-05-24 12:15:51",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "user",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "User",
|
||||
"oldfieldname": "user",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "User",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"fieldname": "territory",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Territory",
|
||||
"oldfieldname": "territory",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Territory",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "naming_series",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Series",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "naming_series",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "[Select]",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "currency",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 0,
|
||||
"label": "Currency",
|
||||
"oldfieldname": "currency",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "Currency",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "selling_price_list",
|
||||
"fieldtype": "Link",
|
||||
"label": "Price List",
|
||||
"oldfieldname": "price_list_name",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "Price List",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Company",
|
||||
"oldfieldname": "company",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Company",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break0",
|
||||
"fieldtype": "Column Break",
|
||||
"oldfieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"description": "Create Stock Ledger Entries when you submit a Sales Invoice",
|
||||
"fieldname": "update_stock",
|
||||
"fieldtype": "Check",
|
||||
"label": "Update Stock",
|
||||
"permlevel": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "customer",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 0,
|
||||
"label": "Customer",
|
||||
"oldfieldname": "customer_account",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Customer",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "cash_bank_account",
|
||||
"fieldtype": "Link",
|
||||
"label": "Cash/Bank Account",
|
||||
"oldfieldname": "cash_bank_account",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "income_account",
|
||||
"fieldtype": "Link",
|
||||
"label": "Income Account",
|
||||
"oldfieldname": "income_account",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)",
|
||||
"fieldname": "expense_account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"label": "Expense Account",
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "warehouse",
|
||||
"fieldtype": "Link",
|
||||
"label": "Warehouse",
|
||||
"oldfieldname": "warehouse",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Warehouse",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "cost_center",
|
||||
"fieldtype": "Link",
|
||||
"label": "Cost Center",
|
||||
"oldfieldname": "cost_center",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Cost Center",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "taxes_and_charges",
|
||||
"fieldtype": "Link",
|
||||
"label": "Taxes and Charges",
|
||||
"oldfieldname": "charge",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Sales Taxes and Charges Template",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "write_off_account",
|
||||
"fieldtype": "Link",
|
||||
"label": "Write Off Account",
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "write_off_cost_center",
|
||||
"fieldtype": "Link",
|
||||
"label": "Write Off Cost Center",
|
||||
"options": "Cost Center",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "letter_head",
|
||||
"fieldtype": "Link",
|
||||
"label": "Letter Head",
|
||||
"oldfieldname": "letter_head",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "Letter Head",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "tc_name",
|
||||
"fieldtype": "Link",
|
||||
"label": "Terms and Conditions",
|
||||
"oldfieldname": "tc_name",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Terms and Conditions",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "select_print_heading",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 0,
|
||||
"label": "Print Heading",
|
||||
"oldfieldname": "select_print_heading",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "Print Heading",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
}
|
||||
],
|
||||
"icon": "icon-cog",
|
||||
"idx": 1,
|
||||
"modified": "2015-05-20 05:38:44.482696",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "POS Profile",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts Manager",
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"apply_user_permissions": 1,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts User",
|
||||
"submit": 0
|
||||
}
|
||||
],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "user"
|
||||
}
|
||||
10
erpnext/accounts/doctype/pos_setting/pos_setting.py → erpnext/accounts/doctype/pos_profile/pos_profile.py
Executable file → Normal file
10
erpnext/accounts/doctype/pos_setting/pos_setting.py → erpnext/accounts/doctype/pos_profile/pos_profile.py
Executable file → Normal file
@@ -8,22 +8,22 @@ from frappe.utils import cint
|
||||
|
||||
from frappe.model.document import Document
|
||||
|
||||
class POSSetting(Document):
|
||||
class POSProfile(Document):
|
||||
def validate(self):
|
||||
self.check_for_duplicate()
|
||||
self.validate_expense_account()
|
||||
self.validate_all_link_fields()
|
||||
|
||||
def check_for_duplicate(self):
|
||||
res = frappe.db.sql("""select name, user from `tabPOS Setting`
|
||||
res = frappe.db.sql("""select name, user from `tabPOS Profile`
|
||||
where ifnull(user, '') = %s and name != %s and company = %s""",
|
||||
(self.user, self.name, self.company))
|
||||
if res:
|
||||
if res[0][1]:
|
||||
msgprint(_("POS Setting {0} already created for user: {1} and company {2}").format(res[0][0],
|
||||
msgprint(_("POS Profile {0} already created for user: {1} and company {2}").format(res[0][0],
|
||||
res[0][1], self.company), raise_exception=1)
|
||||
else:
|
||||
msgprint(_("Global POS Setting {0} already created for company {1}").format(res[0][0],
|
||||
msgprint(_("Global POS Profile {0} already created for company {1}").format(res[0][0],
|
||||
self.company), raise_exception=1)
|
||||
|
||||
def validate_expense_account(self):
|
||||
@@ -57,7 +57,7 @@ class POSSetting(Document):
|
||||
condition = ""
|
||||
|
||||
pos_view_users = frappe.db.sql_list("""select user
|
||||
from `tabPOS Setting` {0}""".format(condition))
|
||||
from `tabPOS Profile` {0}""".format(condition))
|
||||
|
||||
for user in pos_view_users:
|
||||
if user:
|
||||
@@ -1,3 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
@@ -5,7 +6,7 @@ from __future__ import unicode_literals
|
||||
import frappe
|
||||
import unittest
|
||||
|
||||
test_records = frappe.get_test_records('POS Setting')
|
||||
# test_records = frappe.get_test_records('POS Profile')
|
||||
|
||||
class TestPOSSetting(unittest.TestCase):
|
||||
class TestPOSProfile(unittest.TestCase):
|
||||
pass
|
||||
@@ -1 +0,0 @@
|
||||
Standard settings for Point of Sales (POS) type of Sales Invoice.
|
||||
@@ -1 +0,0 @@
|
||||
from __future__ import unicode_literals
|
||||
@@ -1,263 +0,0 @@
|
||||
{
|
||||
"allow_rename": 0,
|
||||
"autoname": "hash",
|
||||
"creation": "2013-05-24 12:15:51",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "user",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "User",
|
||||
"oldfieldname": "user",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "User",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"fieldname": "territory",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Territory",
|
||||
"oldfieldname": "territory",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Territory",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "naming_series",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Series",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "naming_series",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "[Select]",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "currency",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 0,
|
||||
"label": "Currency",
|
||||
"oldfieldname": "currency",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "Currency",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "selling_price_list",
|
||||
"fieldtype": "Link",
|
||||
"label": "Price List",
|
||||
"oldfieldname": "price_list_name",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "Price List",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Company",
|
||||
"oldfieldname": "company",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Company",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break0",
|
||||
"fieldtype": "Column Break",
|
||||
"oldfieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"description": "Create Stock Ledger Entries when you submit a Sales Invoice",
|
||||
"fieldname": "update_stock",
|
||||
"fieldtype": "Check",
|
||||
"label": "Update Stock",
|
||||
"permlevel": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "customer",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 0,
|
||||
"label": "Customer",
|
||||
"oldfieldname": "customer_account",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Customer",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "cash_bank_account",
|
||||
"fieldtype": "Link",
|
||||
"label": "Cash/Bank Account",
|
||||
"oldfieldname": "cash_bank_account",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "income_account",
|
||||
"fieldtype": "Link",
|
||||
"label": "Income Account",
|
||||
"oldfieldname": "income_account",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)",
|
||||
"fieldname": "expense_account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"label": "Expense Account",
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "warehouse",
|
||||
"fieldtype": "Link",
|
||||
"label": "Warehouse",
|
||||
"oldfieldname": "warehouse",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Warehouse",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "cost_center",
|
||||
"fieldtype": "Link",
|
||||
"label": "Cost Center",
|
||||
"oldfieldname": "cost_center",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Cost Center",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "taxes_and_charges",
|
||||
"fieldtype": "Link",
|
||||
"label": "Taxes and Charges",
|
||||
"oldfieldname": "charge",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Sales Taxes and Charges Template",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "write_off_account",
|
||||
"fieldtype": "Link",
|
||||
"label": "Write Off Account",
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "write_off_cost_center",
|
||||
"fieldtype": "Link",
|
||||
"label": "Write Off Cost Center",
|
||||
"options": "Cost Center",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "letter_head",
|
||||
"fieldtype": "Link",
|
||||
"label": "Letter Head",
|
||||
"oldfieldname": "letter_head",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "Letter Head",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "tc_name",
|
||||
"fieldtype": "Link",
|
||||
"label": "Terms and Conditions",
|
||||
"oldfieldname": "tc_name",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Terms and Conditions",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "select_print_heading",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 0,
|
||||
"label": "Print Heading",
|
||||
"oldfieldname": "select_print_heading",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "Print Heading",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
}
|
||||
],
|
||||
"icon": "icon-cog",
|
||||
"idx": 1,
|
||||
"modified": "2015-02-05 05:11:42.344181",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "POS Setting",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts Manager",
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"apply_user_permissions": 1,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts User",
|
||||
"submit": 0
|
||||
}
|
||||
],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "user"
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
[]
|
||||
@@ -217,7 +217,7 @@
|
||||
"depends_on": "eval:doc.price_or_discount==\"Discount Percentage\"",
|
||||
"fieldname": "discount_percentage",
|
||||
"fieldtype": "Float",
|
||||
"label": "Discount Percentage",
|
||||
"label": "Discount on Price List Rate (%)",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
@@ -245,7 +245,7 @@
|
||||
"icon": "icon-gift",
|
||||
"idx": 1,
|
||||
"istable": 0,
|
||||
"modified": "2015-02-26 04:26:13.240166",
|
||||
"modified": "2015-05-27 02:47:16.777466",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Pricing Rule",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -105,10 +105,11 @@
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "price_list_rate",
|
||||
"fieldname": "discount_percentage",
|
||||
"fieldtype": "Percent",
|
||||
"in_list_view": 1,
|
||||
"label": "Discount %",
|
||||
"label": "Discount on Price List Rate (%)",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0
|
||||
@@ -451,7 +452,7 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2015-02-23 15:35:32.895515",
|
||||
"modified": "2015-05-27 02:47:16.341373",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Invoice Item",
|
||||
|
||||
@@ -23,7 +23,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
this.frm.set_value("is_pos", 1);
|
||||
this.is_pos(function() {
|
||||
if (cint(frappe.defaults.get_user_defaults("fs_pos_view"))===1)
|
||||
erpnext.pos.toggle(me.frm);
|
||||
erpnext.pos.toggle(me.frm, true);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -75,7 +75,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
}
|
||||
|
||||
// Show buttons only when pos view is active
|
||||
if (doc.docstatus===0 && !this.pos_active) {
|
||||
if (doc.docstatus===0 && !cur_frm.page.current_view_name!=="pos") {
|
||||
cur_frm.cscript.sales_order_btn();
|
||||
cur_frm.cscript.delivery_note_btn();
|
||||
}
|
||||
@@ -253,7 +253,7 @@ cur_frm.cscript.mode_of_payment = function(doc) {
|
||||
if(r.message) {
|
||||
cur_frm.set_value("cash_bank_account", r.message["account"]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -160,12 +160,12 @@ class SalesInvoice(SellingController):
|
||||
frappe.throw(_("Time Log Batch {0} must be 'Submitted'").format(d.time_log_batch))
|
||||
|
||||
def set_pos_fields(self, for_validate=False):
|
||||
"""Set retail related fields from pos settings"""
|
||||
"""Set retail related fields from POS Profiles"""
|
||||
if cint(self.is_pos) != 1:
|
||||
return
|
||||
|
||||
from erpnext.stock.get_item_details import get_pos_settings_item_details, get_pos_settings
|
||||
pos = get_pos_settings(self.company)
|
||||
from erpnext.stock.get_item_details import get_pos_profiles_item_details, get_pos_profiles
|
||||
pos = get_pos_profiles(self.company)
|
||||
|
||||
if pos:
|
||||
if not for_validate and not self.customer:
|
||||
@@ -184,7 +184,7 @@ class SalesInvoice(SellingController):
|
||||
# set pos values in items
|
||||
for item in self.get("items"):
|
||||
if item.get('item_code'):
|
||||
for fname, val in get_pos_settings_item_details(pos,
|
||||
for fname, val in get_pos_profiles_item_details(pos,
|
||||
frappe._dict(item.as_dict()), pos).items():
|
||||
|
||||
if (not for_validate) or (for_validate and not item.get(fname)):
|
||||
@@ -371,24 +371,24 @@ class SalesInvoice(SellingController):
|
||||
|
||||
|
||||
def get_warehouse(self):
|
||||
user_pos_setting = frappe.db.sql("""select name, warehouse from `tabPOS Setting`
|
||||
user_pos_profile = frappe.db.sql("""select name, warehouse from `tabPOS Profile`
|
||||
where ifnull(user,'') = %s and company = %s""", (frappe.session['user'], self.company))
|
||||
warehouse = user_pos_setting[0][1] if user_pos_setting else None
|
||||
warehouse = user_pos_profile[0][1] if user_pos_profile else None
|
||||
|
||||
if not warehouse:
|
||||
global_pos_setting = frappe.db.sql("""select name, warehouse from `tabPOS Setting`
|
||||
global_pos_profile = frappe.db.sql("""select name, warehouse from `tabPOS Profile`
|
||||
where ifnull(user,'') = '' and company = %s""", self.company)
|
||||
|
||||
if global_pos_setting:
|
||||
warehouse = global_pos_setting[0][1]
|
||||
elif not user_pos_setting:
|
||||
msgprint(_("POS Setting required to make POS Entry"), raise_exception=True)
|
||||
if global_pos_profile:
|
||||
warehouse = global_pos_profile[0][1]
|
||||
elif not user_pos_profile:
|
||||
msgprint(_("POS Profile required to make POS Entry"), raise_exception=True)
|
||||
|
||||
return warehouse
|
||||
|
||||
def on_update(self):
|
||||
if cint(self.update_stock) == 1:
|
||||
# Set default warehouse from pos setting
|
||||
# Set default warehouse from POS Profile
|
||||
if cint(self.is_pos) == 1:
|
||||
w = self.get_warehouse()
|
||||
if w:
|
||||
|
||||
@@ -462,7 +462,7 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
|
||||
def test_pos_gl_entry_with_aii(self):
|
||||
set_perpetual_inventory()
|
||||
self.make_pos_setting()
|
||||
self.make_pos_profile()
|
||||
|
||||
self._insert_purchase_receipt()
|
||||
|
||||
@@ -517,19 +517,19 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
|
||||
set_perpetual_inventory(0)
|
||||
|
||||
frappe.db.sql("delete from `tabPOS Setting`")
|
||||
frappe.db.sql("delete from `tabPOS Profile`")
|
||||
|
||||
def make_pos_setting(self):
|
||||
pos_setting = frappe.get_doc({
|
||||
def make_pos_profile(self):
|
||||
pos_profile = frappe.get_doc({
|
||||
"cash_bank_account": "_Test Account Bank Account - _TC",
|
||||
"company": "_Test Company",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"currency": "INR",
|
||||
"doctype": "POS Setting",
|
||||
"doctype": "POS Profile",
|
||||
"expense_account": "_Test Account Cost for Goods Sold - _TC",
|
||||
"income_account": "Sales - _TC",
|
||||
"name": "_Test POS Setting",
|
||||
"naming_series": "_T-POS Setting-",
|
||||
"name": "_Test POS Profile",
|
||||
"naming_series": "_T-POS Profile-",
|
||||
"selling_price_list": "_Test Price List",
|
||||
"territory": "_Test Territory",
|
||||
"warehouse": "_Test Warehouse - _TC",
|
||||
@@ -537,8 +537,8 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
"write_off_cost_center": "_Test Write Off Cost Center - _TC"
|
||||
})
|
||||
|
||||
if not frappe.db.exists("POS Setting", "_Test POS Setting"):
|
||||
pos_setting.insert()
|
||||
if not frappe.db.exists("POS Profile", "_Test POS Profile"):
|
||||
pos_profile.insert()
|
||||
|
||||
def test_si_gl_entry_with_aii_and_update_stock_with_warehouse_but_no_account(self):
|
||||
set_perpetual_inventory()
|
||||
|
||||
@@ -98,10 +98,11 @@
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "price_list_rate",
|
||||
"fieldname": "discount_percentage",
|
||||
"fieldtype": "Percent",
|
||||
"in_list_view": 1,
|
||||
"label": "Discount (%)",
|
||||
"label": "Discount on Price List Rate (%)",
|
||||
"oldfieldname": "adj_rate",
|
||||
"oldfieldtype": "Float",
|
||||
"permlevel": 0,
|
||||
@@ -504,7 +505,7 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2015-03-23 14:56:45.641026",
|
||||
"modified": "2015-05-27 02:47:15.645114",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice Item",
|
||||
|
||||
@@ -55,7 +55,7 @@ frappe.pages["Accounts Browser"].on_page_load = function(wrapper){
|
||||
.change(function() {
|
||||
var ctype = frappe.get_route()[1] || 'Account';
|
||||
erpnext.account_chart = new erpnext.AccountsChart(ctype, $(this).val(),
|
||||
chart_area.get(0));
|
||||
chart_area.get(0), wrapper.page);
|
||||
})
|
||||
|
||||
// load up companies
|
||||
@@ -75,19 +75,23 @@ frappe.pages["Accounts Browser"].on_page_show = function(wrapper){
|
||||
// set route
|
||||
var ctype = frappe.get_route()[1] || 'Account';
|
||||
|
||||
|
||||
|
||||
if(erpnext.account_chart && erpnext.account_chart.ctype != ctype) {
|
||||
wrapper.$company_select.change();
|
||||
}
|
||||
}
|
||||
|
||||
erpnext.AccountsChart = Class.extend({
|
||||
init: function(ctype, company, wrapper) {
|
||||
init: function(ctype, company, wrapper, page) {
|
||||
$(wrapper).empty();
|
||||
var me = this;
|
||||
me.ctype = ctype;
|
||||
me.can_create = frappe.model.can_create(this.ctype);
|
||||
me.can_delete = frappe.model.can_delete(this.ctype);
|
||||
me.can_write = frappe.model.can_write(this.ctype);
|
||||
me.page = page;
|
||||
me.set_title();
|
||||
|
||||
// __("Accounts"), __("Cost Centers")
|
||||
|
||||
@@ -169,9 +173,9 @@ erpnext.AccountsChart = Class.extend({
|
||||
set_title: function(val) {
|
||||
var chart_str = this.ctype=="Account" ? __("Chart of Accounts") : __("Chart of Cost Centers");
|
||||
if(val) {
|
||||
wrapper.page.set_title(chart_str + " - " + cstr(val));
|
||||
this.page.set_title(chart_str + " - " + cstr(val));
|
||||
} else {
|
||||
wrapper.page.set_title(chart_str);
|
||||
this.page.set_title(chart_str);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ frappe.pages['pos'].on_page_load = function(wrapper) {
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
url: "/api/resource/POS Setting",
|
||||
url: "/api/resource/POS Profile",
|
||||
success: function(data) {
|
||||
if(!data.data.length) {
|
||||
page.main.find(".pos-setting-message").removeClass('hide');
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"creation": "2012-04-11 13:16:56",
|
||||
"doc_type": "Journal Entry",
|
||||
"docstatus": 0,
|
||||
"doctype": "Print Format",
|
||||
"html": "<div style=\"position: relative\">\n\n\t{%- from \"templates/print_formats/standard_macros.html\" import add_header -%}\n<div class=\"page-break\">\n {%- if not doc.get(\"print_heading\") and not doc.get(\"select_print_heading\") \n and doc.set(\"select_print_heading\", _(\"Payment Advice\")) -%}{%- endif -%}\n {{ add_header(0, 1, doc, letter_head, no_letterhead) }}\n\n{%- for label, value in (\n (_(\"Voucher Date\"), frappe.utils.formatdate(doc.voucher_date)),\n (_(\"Reference / Cheque No.\"), doc.cheque_no),\n (_(\"Reference / Cheque Date\"), frappe.utils.formatdate(doc.cheque_date))\n ) -%}\n <div class=\"row\">\n <div class=\"col-xs-4\"><label class=\"text-right\">{{ label }}</label></div>\n <div class=\"col-xs-8\">{{ value }}</div>\n </div>\n{%- endfor -%}\n\t<hr>\n\t<p>{{ _(\"This amount is in full / part settlement of the listed bills\") }}:</p>\n{%- for label, value in (\n (_(\"Amount\"), \"<strong>\" + doc.get_formatted(\"total_amount\") + \"</strong><br>\" + (doc.total_amount_in_words or \"\") + \"<br>\"),\n (_(\"References\"), doc.remark)\n ) -%}\n <div class=\"row\">\n <div class=\"col-xs-4\"><label class=\"text-right\">{{ label }}</label></div>\n <div class=\"col-xs-8\">{{ value }}</div>\n </div>\n {%- endfor -%}\n <hr>\n\t<div style=\"position: absolute; top: 14cm; left: 0cm;\">\n\t\tPrepared By</div>\n\t<div style=\"position: absolute; top: 14cm; left: 5.5cm;\">\n\t\tAuthorised Signatory</div>\n\t<div style=\"position: absolute; top: 14cm; left: 11cm;\">\n\t\tReceived Payment as Above</div>\n\t<div style=\"position: absolute; top: 16.4cm; left: 5.9cm;\">\n\t\t<strong>_____________</strong></div>\n\t<div style=\"position: absolute; top: 16.7cm; left: 6cm;\">\n\t\t<strong>A/C Payee</strong></div>\n\t<div style=\"position: absolute; top: 16.7cm; left: 5.9cm;\">\n\t\t<strong>_____________</strong></div>\n\t<div style=\"position: absolute; top: 16.9cm; left: 12cm;\">\n\t\t{{ frappe.utils.formatdate(doc.cheque_date) }}</div>\n\t<div style=\"position: absolute; top: 17.9cm; left: 1cm;\">\n\t\t{{ doc.pay_to_recd_from }}</div>\n\t<div style=\"position: absolute; top: 18.6cm; left: 1cm; width: 7cm;\">\n\t\t{{ doc.total_amount_in_words }}</div>\n\t<div style=\"position: absolute; top: 19.7cm; left: 12cm;\">\n\t\t{{ doc.total_amount }}</div>\n</div>",
|
||||
"idx": 1,
|
||||
"modified": "2015-01-12 11:03:17.032512",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Cheque Printing Format",
|
||||
"owner": "Administrator",
|
||||
"print_format_type": "Server",
|
||||
"creation": "2012-04-11 13:16:56",
|
||||
"custom_format": 1,
|
||||
"doc_type": "Journal Entry",
|
||||
"docstatus": 0,
|
||||
"doctype": "Print Format",
|
||||
"html": "<div style=\"position: relative\">\n\n\t{%- from \"templates/print_formats/standard_macros.html\" import add_header -%}\n<div class=\"page-break\">\n {%- if not doc.get(\"print_heading\") and not doc.get(\"select_print_heading\") \n and doc.set(\"select_print_heading\", _(\"Payment Advice\")) -%}{%- endif -%}\n {{ add_header(0, 1, doc, letter_head, no_letterhead) }}\n\n{%- for label, value in (\n (_(\"Voucher Date\"), frappe.utils.formatdate(doc.voucher_date)),\n (_(\"Reference / Cheque No.\"), doc.cheque_no),\n (_(\"Reference / Cheque Date\"), frappe.utils.formatdate(doc.cheque_date))\n ) -%}\n <div class=\"row\">\n <div class=\"col-xs-4\"><label class=\"text-right\">{{ label }}</label></div>\n <div class=\"col-xs-8\">{{ value }}</div>\n </div>\n{%- endfor -%}\n\t<hr>\n\t<p>{{ _(\"This amount is in full / part settlement of the listed bills\") }}:</p>\n{%- for label, value in (\n (_(\"Amount\"), \"<strong>\" + doc.get_formatted(\"total_amount\") + \"</strong><br>\" + (doc.total_amount_in_words or \"\") + \"<br>\"),\n (_(\"References\"), doc.remark)\n ) -%}\n <div class=\"row\">\n <div class=\"col-xs-4\"><label class=\"text-right\">{{ label }}</label></div>\n <div class=\"col-xs-8\">{{ value }}</div>\n </div>\n {%- endfor -%}\n <hr>\n\t<div style=\"position: absolute; top: 14cm; left: 0cm;\">\n\t\tPrepared By</div>\n\t<div style=\"position: absolute; top: 14cm; left: 5.5cm;\">\n\t\tAuthorised Signatory</div>\n\t<div style=\"position: absolute; top: 14cm; left: 11cm;\">\n\t\tReceived Payment as Above</div>\n\t<div style=\"position: absolute; top: 16.4cm; left: 5.9cm;\">\n\t\t<strong>_____________</strong></div>\n\t<div style=\"position: absolute; top: 16.7cm; left: 6cm;\">\n\t\t<strong>A/C Payee</strong></div>\n\t<div style=\"position: absolute; top: 16.7cm; left: 5.9cm;\">\n\t\t<strong>_____________</strong></div>\n\t<div style=\"position: absolute; top: 16.9cm; left: 12cm;\">\n\t\t{{ frappe.utils.formatdate(doc.cheque_date) }}</div>\n\t<div style=\"position: absolute; top: 17.9cm; left: 1cm;\">\n\t\t{{ doc.pay_to_recd_from }}</div>\n\t<div style=\"position: absolute; top: 18.6cm; left: 1cm; width: 7cm;\">\n\t\t{{ doc.total_amount_in_words }}</div>\n\t<div style=\"position: absolute; top: 19.7cm; left: 12cm;\">\n\t\t{{ doc.get_formatted(\"total_amount\") }}</div>\n</div>",
|
||||
"idx": 1,
|
||||
"modified": "2015-05-29 01:57:51.203850",
|
||||
"modified_by": "Administrator",
|
||||
"name": "Cheque Printing Format",
|
||||
"owner": "Administrator",
|
||||
"print_format_type": "Server",
|
||||
"standard": "Yes"
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ def execute(filters=None):
|
||||
def get_provisional_profit_loss(asset, liability, equity, period_list):
|
||||
if asset and (liability or equity):
|
||||
provisional_profit_loss = {
|
||||
"account_name": _("Provisional Profit / Loss (Credit)"),
|
||||
"account_name": "'" + _("Provisional Profit / Loss (Credit)") + "'",
|
||||
"account": None,
|
||||
"warn_if_negative": True
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ def execute(filters=None):
|
||||
data += [
|
||||
get_balance_row(_("System Balance"), balance_as_per_system),
|
||||
[""]*len(columns),
|
||||
["", _("Amounts not reflected in bank"), total_debit, total_credit, "", "", "", ""],
|
||||
["", '"' + _("Amounts not reflected in bank") + '"', total_debit, total_credit, "", "", "", ""],
|
||||
get_balance_row(_("Amounts not reflected in system"), amounts_not_reflected_in_system),
|
||||
[""]*len(columns),
|
||||
get_balance_row(_("Expected balance as per bank"), bank_bal)
|
||||
@@ -68,6 +68,6 @@ def get_entries(filters):
|
||||
|
||||
def get_balance_row(label, amount):
|
||||
if amount > 0:
|
||||
return ["", label, amount, 0, "", "", "", ""]
|
||||
return ["", '"' + label + '"', amount, 0, "", "", "", ""]
|
||||
else:
|
||||
return ["", label, 0, abs(amount), "", "", "", ""]
|
||||
return ["", '"' + label + '"', 0, abs(amount), "", "", "", ""]
|
||||
|
||||
@@ -146,7 +146,7 @@ def prepare_data(accounts, balance_must_be, period_list):
|
||||
|
||||
def add_total_row(out, balance_must_be, period_list):
|
||||
row = {
|
||||
"account_name": _("Total ({0})").format(balance_must_be),
|
||||
"account_name": "'" + _("Total ({0})").format(balance_must_be) + "'",
|
||||
"account": None
|
||||
}
|
||||
for period in period_list:
|
||||
@@ -207,7 +207,7 @@ def filter_accounts(accounts, depth=10):
|
||||
add_to_list(None, 0)
|
||||
|
||||
return filtered_accounts, accounts_by_name
|
||||
|
||||
|
||||
def sort_root_accounts(roots):
|
||||
"""Sort root types as Asset, Liability, Equity, Income, Expense"""
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{%= frappe.boot.letter_heads[frappe.defaults.get_default("letter_head")] %}
|
||||
</div>
|
||||
<h2 class="text-center">{%= __("Statement of Account") %}</h2>
|
||||
<h4 class="text-center">{%= filters.account && (filters.account + ", ") || "" %} {%= filters.company %}</h4>
|
||||
<h4 class="text-center">{%= (filters.party || filters.account) && ((filters.party || filters.account) + ", ") || "" %} {%= filters.company %}</h4>
|
||||
<h5 class="text-center">
|
||||
{%= dateutil.str_to_user(filters.from_date) %}
|
||||
{%= __("to") %}
|
||||
@@ -26,15 +26,20 @@
|
||||
<td>{%= dateutil.str_to_user(data[i][__("Posting Date")]) %}</td>
|
||||
<td>{%= data[i][__("Voucher Type")] %}
|
||||
<br>{%= data[i][__("Voucher No")] %}</td>
|
||||
<td>{%= data[i][__("Account")] %}
|
||||
<br>{%= __("Against") %}: {%= data[i][__("Against Account")] %}
|
||||
<td>
|
||||
{% if(!(filters.party || filters.account)) { %}
|
||||
{%= data[i][__("Party")] || data[i][__("Account")] %}
|
||||
<br>
|
||||
{% } %}
|
||||
|
||||
{{ __("Against") }}: {%= data[i][__("Against Account")] %}
|
||||
<br>{%= __("Remarks") %}: {%= data[i][__("Remarks")] %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i][__("Debit")]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i][__("Credit")]) %}</td>
|
||||
{% } else { %}
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td><b>{%= data[i][__("Account")] || " " %}</b></td>
|
||||
<td><b>{%= frappe.format(data[i][__("Account")], {fieldtype: "Link"}) || " " %}</b></td>
|
||||
<td style="text-align: right">
|
||||
{%= data[i][__("Account")] && format_currency(data[i][__("Debit")]) %}</td>
|
||||
<td style="text-align: right">
|
||||
|
||||
@@ -9,7 +9,7 @@ from frappe import _
|
||||
def execute(filters=None):
|
||||
account_details = {}
|
||||
for acc in frappe.db.sql("""select name, is_group from tabAccount""", as_dict=1):
|
||||
account_details.setdefault(acc.name, acc)
|
||||
account_details.setdefault(acc.name, acc)
|
||||
|
||||
validate_filters(filters, account_details)
|
||||
validate_party(filters)
|
||||
@@ -82,8 +82,6 @@ def get_conditions(filters):
|
||||
lft, rgt = frappe.db.get_value("Account", filters["account"], ["lft", "rgt"])
|
||||
conditions.append("""account in (select name from tabAccount
|
||||
where lft>=%s and rgt<=%s and docstatus<2)""" % (lft, rgt))
|
||||
else:
|
||||
conditions.append("posting_date between %(from_date)s and %(to_date)s")
|
||||
|
||||
if filters.get("voucher_no"):
|
||||
conditions.append("voucher_no=%(voucher_no)s")
|
||||
@@ -107,31 +105,31 @@ def get_data_with_opening_closing(filters, account_details, gl_entries):
|
||||
opening, total_debit, total_credit, gle_map = get_accountwise_gle(filters, gl_entries, gle_map)
|
||||
|
||||
# Opening for filtered account
|
||||
if filters.get("account"):
|
||||
data += [get_balance_row("Opening", opening), {}]
|
||||
if filters.get("account") or filters.get("party"):
|
||||
data += [get_balance_row(_("Opening"), opening), {}]
|
||||
|
||||
for acc, acc_dict in gle_map.items():
|
||||
if acc_dict.entries:
|
||||
# Opening for individual ledger, if grouped by account
|
||||
if filters.get("group_by_account"):
|
||||
data.append(get_balance_row("Opening", acc_dict.opening))
|
||||
data.append(get_balance_row(_("Opening"), acc_dict.opening))
|
||||
|
||||
data += acc_dict.entries
|
||||
|
||||
# Totals and closing for individual ledger, if grouped by account
|
||||
if filters.get("group_by_account"):
|
||||
data += [{"account": "Totals", "debit": acc_dict.total_debit,
|
||||
data += [{"account": "'" + _("Totals") + "'", "debit": acc_dict.total_debit,
|
||||
"credit": acc_dict.total_credit},
|
||||
get_balance_row("Closing (Opening + Totals)",
|
||||
get_balance_row(_("Closing (Opening + Totals)"),
|
||||
(acc_dict.opening + acc_dict.total_debit - acc_dict.total_credit)), {}]
|
||||
|
||||
# Total debit and credit between from and to date
|
||||
if total_debit or total_credit:
|
||||
data.append({"account": "Totals", "debit": total_debit, "credit": total_credit})
|
||||
data.append({"account": "'" + _("Totals") + "'", "debit": total_debit, "credit": total_credit})
|
||||
|
||||
# Closing for filtered account
|
||||
if filters.get("account"):
|
||||
data.append(get_balance_row("Closing (Opening + Totals)",
|
||||
if filters.get("account") or filters.get("party"):
|
||||
data.append(get_balance_row(_("Closing (Opening + Totals)"),
|
||||
(opening + total_debit - total_credit)))
|
||||
|
||||
return data
|
||||
@@ -153,9 +151,10 @@ def get_accountwise_gle(filters, gl_entries, gle_map):
|
||||
|
||||
for gle in gl_entries:
|
||||
amount = flt(gle.debit, 3) - flt(gle.credit, 3)
|
||||
if filters.get("account") and gle.posting_date < getdate(filters.from_date):
|
||||
if gle.posting_date < getdate(filters.from_date):
|
||||
gle_map[gle.account].opening += amount
|
||||
opening += amount
|
||||
if filters.get("account") or filters.get("party"):
|
||||
opening += amount
|
||||
elif gle.posting_date <= getdate(filters.to_date):
|
||||
gle_map[gle.account].entries.append(gle)
|
||||
gle_map[gle.account].total_debit += flt(gle.debit, 3)
|
||||
@@ -168,7 +167,7 @@ def get_accountwise_gle(filters, gl_entries, gle_map):
|
||||
|
||||
def get_balance_row(label, balance):
|
||||
return {
|
||||
"account": label,
|
||||
"account": "'" + label + "'",
|
||||
"debit": balance if balance > 0 else 0,
|
||||
"credit": -1*balance if balance < 0 else 0,
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ class GrossProfitGenerator(object):
|
||||
|
||||
row.base_amount = flt(row.base_net_amount)
|
||||
|
||||
sales_boms = self.sales_boms.get(row.parenttype, {}).get(row.name, frappe._dict())
|
||||
sales_boms = self.sales_boms.get(row.parenttype, {}).get(row.parent, frappe._dict())
|
||||
|
||||
# get buying amount
|
||||
if row.item_code in sales_boms:
|
||||
@@ -158,7 +158,7 @@ class GrossProfitGenerator(object):
|
||||
|
||||
def get_buying_amount_from_sales_bom(self, row, sales_bom):
|
||||
buying_amount = 0.0
|
||||
for bom_item in sales_bom[row.item_code]:
|
||||
for bom_item in sales_bom:
|
||||
if bom_item.get("parent_detail_docname")==row.item_row:
|
||||
buying_amount += self.get_buying_amount(row, bom_item.item_code)
|
||||
|
||||
@@ -174,14 +174,17 @@ class GrossProfitGenerator(object):
|
||||
return flt(row.qty) * item_rate
|
||||
|
||||
else:
|
||||
if row.dn_detail:
|
||||
row.parenttype = "Delivery Note"
|
||||
row.parent = row.delivery_note
|
||||
row.item_row = row.dn_detail
|
||||
if row.update_stock or row.dn_detail:
|
||||
if row.dn_detail:
|
||||
row.parenttype = "Delivery Note"
|
||||
row.parent = row.delivery_note
|
||||
row.item_row = row.dn_detail
|
||||
|
||||
my_sle = self.sle.get((item_code, row.warehouse))
|
||||
for i, sle in enumerate(my_sle):
|
||||
# find the stock valution rate from stock ledger entry
|
||||
print sle.voucher_type, row.parenttype, sle.voucher_no, row.parent, \
|
||||
sle.voucher_detail_no, row.item_row
|
||||
if sle.voucher_type == row.parenttype and row.parent == sle.voucher_no and \
|
||||
sle.voucher_detail_no == row.item_row:
|
||||
previous_stock_value = len(my_sle) > i+1 and \
|
||||
@@ -215,7 +218,7 @@ class GrossProfitGenerator(object):
|
||||
if self.filters.to_date:
|
||||
conditions += " and posting_date <= %(to_date)s"
|
||||
|
||||
self.si_list = frappe.db.sql("""select item.parenttype, si.name,
|
||||
self.si_list = frappe.db.sql("""select item.parenttype, item.parent,
|
||||
si.posting_date, si.posting_time, si.project_name, si.update_stock,
|
||||
si.customer, si.customer_group, si.territory,
|
||||
item.item_code, item.item_name, item.description, item.warehouse,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import msgprint, _
|
||||
from frappe import _
|
||||
from frappe.utils import flt
|
||||
|
||||
def execute(filters=None):
|
||||
@@ -23,7 +23,7 @@ def execute(filters=None):
|
||||
purchase_receipt = d.purchase_receipt
|
||||
elif d.po_detail:
|
||||
purchase_receipt = ", ".join(frappe.db.sql_list("""select distinct parent
|
||||
from `tabPurchase Receipt Item` where docstatus=1 and po_detail=%s""", d.po_detail))
|
||||
from `tabPurchase Receipt Item` where docstatus=1 and prevdoc_detail_docname=%s""", d.po_detail))
|
||||
|
||||
expense_account = d.expense_account or aii_account_map.get(d.company)
|
||||
row = [d.item_code, d.item_name, d.item_group, d.parent, d.posting_date, d.supplier,
|
||||
|
||||
@@ -27,7 +27,7 @@ def execute(filters=None):
|
||||
def get_net_profit_loss(income, expense, period_list):
|
||||
if income and expense:
|
||||
net_profit_loss = {
|
||||
"account_name": _("Net Profit / Loss"),
|
||||
"account_name": "'" + _("Net Profit / Loss") + "'",
|
||||
"account": None,
|
||||
"warn_if_negative": True
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ def get_invoice_tax_map(invoice_list, invoice_expense_map, expense_accounts):
|
||||
return invoice_expense_map, invoice_tax_map
|
||||
|
||||
def get_invoice_po_pr_map(invoice_list):
|
||||
pi_items = frappe.db.sql("""select parent, purchase_order, purchase_receipt, po_detail
|
||||
pi_items = frappe.db.sql("""select parent, purchase_order, purchase_receipt, po_detail,
|
||||
project_name from `tabPurchase Invoice Item` where parent in (%s)
|
||||
and (ifnull(purchase_order, '') != '' or ifnull(purchase_receipt, '') != '')""" %
|
||||
', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]), as_dict=1)
|
||||
@@ -160,7 +160,7 @@ def get_invoice_po_pr_map(invoice_list):
|
||||
pr_list = [d.purchase_receipt]
|
||||
elif d.po_detail:
|
||||
pr_list = frappe.db.sql_list("""select distinct parent from `tabPurchase Receipt Item`
|
||||
where docstatus=1 and po_detail=%s""", d.pr_detail)
|
||||
where docstatus=1 and prevdoc_detail_docname=%s""", d.po_detail)
|
||||
|
||||
if pr_list:
|
||||
invoice_po_pr_map.setdefault(d.parent, frappe._dict()).setdefault("purchase_receipt", pr_list)
|
||||
|
||||
@@ -18,11 +18,11 @@ def get_fiscal_year(date=None, fiscal_year=None, label="Date", verbose=1, compan
|
||||
|
||||
def get_fiscal_years(transaction_date=None, fiscal_year=None, label="Date", verbose=1, company=None):
|
||||
# if year start date is 2012-04-01, year end date should be 2013-03-31 (hence subdate)
|
||||
cond = ""
|
||||
cond = " ifnull(disabled, 0) = 0"
|
||||
if fiscal_year:
|
||||
cond = "fy.name = %(fiscal_year)s"
|
||||
cond += " and fy.name = %(fiscal_year)s"
|
||||
else:
|
||||
cond = "%(transaction_date)s >= fy.year_start_date and %(transaction_date)s <= fy.year_end_date"
|
||||
cond += " and %(transaction_date)s >= fy.year_start_date and %(transaction_date)s <= fy.year_end_date"
|
||||
|
||||
if company:
|
||||
cond += """ and (not exists(select name from `tabFiscal Year Company` fyc where fyc.parent = fy.name)
|
||||
@@ -36,7 +36,7 @@ def get_fiscal_years(transaction_date=None, fiscal_year=None, label="Date", verb
|
||||
})
|
||||
|
||||
if not fy:
|
||||
error_msg = _("""{0} {1} not in any Fiscal Year. For more details check {2}.""").format(label, formatdate(transaction_date), "https://erpnext.com/kb/accounts/fiscal-year-error")
|
||||
error_msg = _("""{0} {1} not in any active Fiscal Year. For more details check {2}.""").format(label, formatdate(transaction_date), "https://erpnext.com/kb/accounts/fiscal-year-error")
|
||||
if verbose==1: frappe.msgprint(error_msg)
|
||||
raise FiscalYearError, error_msg
|
||||
return fy
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,6 @@ frappe.listview_settings['Purchase Order'] = {
|
||||
return [__("Completed"), "green", "per_received,=,100|per_billed,=,100|status,!=,Stopped"];
|
||||
}
|
||||
},
|
||||
order_by: "per_received asc, modified desc",
|
||||
onload: function(listview) {
|
||||
var method = "erpnext.buying.doctype.purchase_order.purchase_order.stop_or_unstop_purchase_orders";
|
||||
|
||||
|
||||
@@ -80,6 +80,8 @@ def create_purchase_order(**args):
|
||||
po.company = args.company or "_Test Company"
|
||||
po.supplier = args.customer or "_Test Supplier"
|
||||
po.is_subcontracted = args.is_subcontracted or "No"
|
||||
po.currency = args.currency or frappe.db.get_value("Company", po.company, "default_currency")
|
||||
po.conversion_factor = args.conversion_factor or 1
|
||||
|
||||
po.append("items", {
|
||||
"item_code": args.item or args.item_code or "_Test Item",
|
||||
|
||||
@@ -192,10 +192,11 @@
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "price_list_rate",
|
||||
"fieldname": "discount_percentage",
|
||||
"fieldtype": "Percent",
|
||||
"in_list_view": 1,
|
||||
"label": "Discount %",
|
||||
"label": "Discount on Price List Rate (%)",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0
|
||||
@@ -537,7 +538,7 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2015-05-14 14:54:16.899713",
|
||||
"modified": "2015-05-27 02:47:16.553472",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Purchase Order Item",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -121,10 +121,11 @@
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "price_list_rate",
|
||||
"fieldname": "discount_percentage",
|
||||
"fieldtype": "Percent",
|
||||
"in_list_view": 1,
|
||||
"label": "Discount %",
|
||||
"label": "Discount on Price List Rate (%)",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0
|
||||
@@ -412,7 +413,7 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2015-05-14 14:54:36.253819",
|
||||
"modified": "2015-05-27 02:47:15.853886",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Supplier Quotation Item",
|
||||
|
||||
8
erpnext/change_log/v5/v5_0_11.md
Normal file
8
erpnext/change_log/v5/v5_0_11.md
Normal file
@@ -0,0 +1,8 @@
|
||||
- Watch help videos in new module "Learn"
|
||||
- Letter head and Terms removed from Purchase Invoice
|
||||
- Renaming Discount fields to "Discount on Price List Rate"
|
||||
- Backup manager: You you can choose which backup to download
|
||||
- "Reserved Warehouse" is renamed "Delivery Warehouse" in Sales Order
|
||||
- Timezone fixes: See all time-stamps in Events etc in your timezone, if you are not in the system timezone.
|
||||
- POS Setting is renamed to POS Profile
|
||||
- Fixes to POS
|
||||
@@ -113,8 +113,8 @@ def get_data():
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "POS Setting",
|
||||
"label": _("Point-of-Sale Setting"),
|
||||
"name": "POS Profile",
|
||||
"label": _("Point-of-Sale Profile"),
|
||||
"description": _("Rules to calculate shipping amount for a sale")
|
||||
},
|
||||
{
|
||||
@@ -329,4 +329,25 @@ def get_data():
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": _("Help"),
|
||||
"icon": "icon-facetime-video",
|
||||
"items": [
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Chart of Accounts"),
|
||||
"youtube_id": "DyR-DST-PyA"
|
||||
},
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Opening Accounting Balance"),
|
||||
"youtube_id": "kdgM20Q-q68"
|
||||
},
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Setting up Taxes"),
|
||||
"youtube_id": "nQ1zZdPgdaQ"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -156,4 +156,14 @@ def get_data():
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": _("Help"),
|
||||
"items": [
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Customer and Supplier"),
|
||||
"youtube_id": "anoGi_RpQ20"
|
||||
},
|
||||
]
|
||||
},
|
||||
]
|
||||
|
||||
@@ -128,4 +128,14 @@ def get_data():
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": _("Help"),
|
||||
"items": [
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Lead to Quotation"),
|
||||
"youtube_id": "TxYX4r4JAKA"
|
||||
},
|
||||
]
|
||||
},
|
||||
]
|
||||
|
||||
@@ -62,5 +62,12 @@ def get_data():
|
||||
"icon": "icon-phone",
|
||||
"icon": "octicon octicon-issue-opened",
|
||||
"type": "module"
|
||||
},
|
||||
"Learn": {
|
||||
"color": "#7272FF",
|
||||
"force_show": True,
|
||||
"icon": "icon-facetime-video",
|
||||
"type": "module",
|
||||
"is_help": True
|
||||
}
|
||||
}
|
||||
|
||||
138
erpnext/config/learn.py
Normal file
138
erpnext/config/learn.py
Normal file
@@ -0,0 +1,138 @@
|
||||
from __future__ import unicode_literals
|
||||
from frappe import _
|
||||
|
||||
def get_data():
|
||||
return [
|
||||
{
|
||||
"label": _("General"),
|
||||
"items": [
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Navigating"),
|
||||
"youtube_id": "YDoI2DF4Lmc"
|
||||
},
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Setup Wizard"),
|
||||
"youtube_id": "oIOf_zCFWKQ"
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
},
|
||||
{
|
||||
"label": _("Setup"),
|
||||
"items": [
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Data Import and Export"),
|
||||
"youtube_id": "6wiriRKPhmg"
|
||||
},
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Opening Stock Balance"),
|
||||
"youtube_id": "yPgrtfeCTs"
|
||||
},
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Setting up Email"),
|
||||
"youtube_id": "YFYe0DrB95o"
|
||||
},
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Printing and Branding"),
|
||||
"youtube_id": "cKZHcx1znMc"
|
||||
},
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Users and Permissions"),
|
||||
"youtube_id": "fnBoRhBrwR4"
|
||||
},
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Workflow"),
|
||||
"youtube_id": "yObJUg9FxFs"
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": _("Accounts"),
|
||||
"items": [
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Chart of Accounts"),
|
||||
"youtube_id": "DyR-DST-PyA"
|
||||
},
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Setting up Taxes"),
|
||||
"youtube_id": "nQ1zZdPgdaQ"
|
||||
},
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Opening Accounting Balance"),
|
||||
"youtube_id": "kdgM20Q-q68"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": _("CRM"),
|
||||
"items": [
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Lead to Quotation"),
|
||||
"youtube_id": "TxYX4r4JAKA"
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": _("Selling"),
|
||||
"items": [
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Customer and Supplier"),
|
||||
"youtube_id": "anoGi_RpQ20"
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": _("Stock"),
|
||||
"items": [
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Items and Pricing"),
|
||||
"youtube_id": "qXaEwld4_Ps"
|
||||
},
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Opening Stock Balance"),
|
||||
"youtube_id": "yPgrtfeCTs"
|
||||
},
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Item Variants"),
|
||||
"youtube_id": "OGBETlCzU5o"
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": _("Buying"),
|
||||
"items": [
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Customer and Supplier"),
|
||||
"youtube_id": "anoGi_RpQ20"
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": _("Manufacturing"),
|
||||
"items": [
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Bill of Materials"),
|
||||
"youtube_id": "hDV0c1OeWLo"
|
||||
},
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -55,6 +55,14 @@ def get_data():
|
||||
"name": "BOM Replace Tool",
|
||||
"description": _("Replace Item / BOM in all BOMs"),
|
||||
},
|
||||
{
|
||||
"type": "page",
|
||||
"name": "bom-browser",
|
||||
"icon": "icon-sitemap",
|
||||
"label": _("BOM Browser"),
|
||||
"description": _("Tree of Bill of Materials"),
|
||||
"doctype": "BOM"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -97,4 +105,15 @@ def get_data():
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": _("Help"),
|
||||
"icon": "icon-facetime-video",
|
||||
"items": [
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Bill of Materials"),
|
||||
"youtube_id": "hDV0c1OeWLo"
|
||||
},
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -275,4 +275,14 @@ def get_data():
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": _("Help"),
|
||||
"items": [
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Customer and Supplier"),
|
||||
"youtube_id": "anoGi_RpQ20"
|
||||
},
|
||||
]
|
||||
},
|
||||
]
|
||||
|
||||
@@ -43,6 +43,36 @@ def get_data():
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": _("Help"),
|
||||
"items": [
|
||||
{
|
||||
"type": "help",
|
||||
"name": _("Data Import and Export"),
|
||||
"youtube_id": "6wiriRKPhmg"
|
||||
},
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Setting up Email"),
|
||||
"youtube_id": "YFYe0DrB95o"
|
||||
},
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Printing and Branding"),
|
||||
"youtube_id": "cKZHcx1znMc"
|
||||
},
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Users and Permissions"),
|
||||
"youtube_id": "fnBoRhBrwR4"
|
||||
},
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Workflow"),
|
||||
"youtube_id": "yObJUg9FxFs"
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": _("Customize"),
|
||||
"icon": "icon-glass",
|
||||
|
||||
@@ -254,4 +254,25 @@ def get_data():
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": _("Help"),
|
||||
"icon": "icon-facetime-video",
|
||||
"items": [
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Items and Pricing"),
|
||||
"youtube_id": "qXaEwld4_Ps"
|
||||
},
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Opening Stock Balance"),
|
||||
"youtube_id": "yPgrtfeCTs"
|
||||
},
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Item Variants"),
|
||||
"youtube_id": "OGBETlCzU5o"
|
||||
},
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -279,7 +279,7 @@ class BuyingController(StockController):
|
||||
|
||||
def set_qty_as_per_stock_uom(self):
|
||||
for d in self.get("items"):
|
||||
if d.meta.get_field("stock_qty") and not d.stock_qty:
|
||||
if d.meta.get_field("stock_qty"):
|
||||
if not d.conversion_factor:
|
||||
frappe.throw(_("Row {0}: Conversion Factor is mandatory").format(d.idx))
|
||||
d.stock_qty = flt(d.qty) * flt(d.conversion_factor)
|
||||
|
||||
@@ -85,9 +85,9 @@ class SellingController(StockController):
|
||||
existing_shipping_charge = self.get("taxes", filters=shipping_charge)
|
||||
if existing_shipping_charge:
|
||||
# take the last record found
|
||||
existing_shipping_charge[-1].rate = shipping_amount
|
||||
existing_shipping_charge[-1].tax_amount = shipping_amount
|
||||
else:
|
||||
shipping_charge["rate"] = shipping_amount
|
||||
shipping_charge["tax_amount"] = shipping_amount
|
||||
shipping_charge["description"] = shipping_rule.label
|
||||
self.append("taxes", shipping_charge)
|
||||
|
||||
|
||||
@@ -8,7 +8,9 @@ import frappe.utils
|
||||
from frappe import throw, _
|
||||
from frappe.model.document import Document
|
||||
from frappe.email.bulk import check_bulk_limit
|
||||
from frappe.utils.verified_command import get_signed_params, verify_request
|
||||
import erpnext.tasks
|
||||
from erpnext.crm.doctype.newsletter_list.newsletter_list import add_subscribers
|
||||
|
||||
class Newsletter(Document):
|
||||
def onload(self):
|
||||
@@ -87,12 +89,11 @@ def get_lead_options():
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
def unsubscribe(email, name):
|
||||
from frappe.utils.verified_command import verify_request
|
||||
if not verify_request():
|
||||
return
|
||||
|
||||
subs_id = frappe.db.get_value("Newsletter List Subscriber", {"email": email, "newsletter_list": name})
|
||||
if name:
|
||||
if subs_id:
|
||||
subscriber = frappe.get_doc("Newsletter List Subscriber", subs_id)
|
||||
subscriber.unsubscribed = 1
|
||||
subscriber.save(ignore_permissions=True)
|
||||
@@ -123,3 +124,47 @@ def create_lead(email_id):
|
||||
"source": "Email"
|
||||
})
|
||||
lead.insert()
|
||||
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
def subscribe(email):
|
||||
url = frappe.utils.get_url("/api/method/erpnext.crm.doctype.newsletter.newsletter.confirm_subscription") +\
|
||||
"?" + get_signed_params({"email": email})
|
||||
|
||||
messages = (
|
||||
_("Thank you for your interest in subscribing to our updates"),
|
||||
_("Please verify your email id"),
|
||||
url,
|
||||
_("Click here to verify")
|
||||
)
|
||||
|
||||
print url
|
||||
|
||||
content = """
|
||||
<p>{0}. {1}.</p>
|
||||
<p><a href="{2}">{3}</a></p>
|
||||
"""
|
||||
|
||||
frappe.sendmail(email, subject=_("Confirm Your Email"), content=content.format(*messages), bulk=True)
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
def confirm_subscription(email):
|
||||
if not verify_request():
|
||||
return
|
||||
|
||||
if not frappe.db.exists("Newsletter List", _("Website")):
|
||||
frappe.get_doc({
|
||||
"doctype": "Newsletter List",
|
||||
"title": _("Website")
|
||||
}).insert(ignore_permissions=True)
|
||||
|
||||
|
||||
frappe.flags.ignore_permissions = True
|
||||
|
||||
add_subscribers(_("Website"), email)
|
||||
frappe.db.commit()
|
||||
|
||||
frappe.respond_as_web_page(_("Confirmed"), _("{0} has been successfully added to our Newsletter list.").format(email))
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -9,7 +9,16 @@ from urllib import unquote
|
||||
|
||||
class TestNewsletter(unittest.TestCase):
|
||||
def setUp(self):
|
||||
frappe.db.sql("update `tabNewsletter List Subscriber` set unsubscribed = 0")
|
||||
if not frappe.get_all("Newsletter List Subscriber"):
|
||||
for email in ["test_subscriber1@example.com", "test_subscriber2@example.com",
|
||||
"test_subscriber3@example.com"]:
|
||||
frappe.get_doc({
|
||||
"doctype": "Newsletter List Subscriber",
|
||||
"email": email,
|
||||
"newsletter_list": "_Test Newsletter List"
|
||||
}).insert()
|
||||
else:
|
||||
frappe.db.sql("update `tabNewsletter List Subscriber` set unsubscribed = 0")
|
||||
|
||||
def test_send(self):
|
||||
self.send_newsletter()
|
||||
@@ -39,6 +48,4 @@ class TestNewsletter(unittest.TestCase):
|
||||
|
||||
newsletter.send_emails()
|
||||
|
||||
|
||||
|
||||
test_dependencies = ["Newsletter List"]
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import validate_email_add, strip
|
||||
from frappe.utils import validate_email_add
|
||||
from frappe import _
|
||||
from email.utils import parseaddr
|
||||
|
||||
@@ -75,7 +75,7 @@ def add_subscribers(name, email_list):
|
||||
"doctype": "Newsletter List Subscriber",
|
||||
"newsletter_list": name,
|
||||
"email": email
|
||||
}).insert()
|
||||
}).insert(ignore_permissions = frappe.flags.ignore_permissions)
|
||||
|
||||
count += 1
|
||||
else:
|
||||
|
||||
@@ -6,8 +6,6 @@ from __future__ import unicode_literals
|
||||
import frappe
|
||||
import unittest
|
||||
|
||||
# test_records = frappe.get_test_records('Newletter List')
|
||||
|
||||
class TestNewletterList(unittest.TestCase):
|
||||
def test_import(self):
|
||||
new_list = frappe.get_doc({
|
||||
@@ -15,13 +13,13 @@ class TestNewletterList(unittest.TestCase):
|
||||
"title": "_Test Newsletter List 1"
|
||||
}).insert()
|
||||
|
||||
n_leads = frappe.db.count("Lead")
|
||||
|
||||
n_leads = frappe.db.sql("select count(distinct email_id) from `tabLead`")[0][0]
|
||||
|
||||
added = new_list.import_from("Lead")
|
||||
|
||||
self.assertEquals(added, n_leads)
|
||||
|
||||
frappe.delete_doc("Newsletter List", new_list.name)
|
||||
def tearDown(self):
|
||||
frappe.delete_doc("Newsletter List", "_Test Newsletter List 1")
|
||||
|
||||
test_dependencies = ["Lead"]
|
||||
|
||||
|
||||
@@ -2,20 +2,5 @@
|
||||
{
|
||||
"doctype": "Newsletter List",
|
||||
"title": "_Test Newsletter List"
|
||||
},
|
||||
{
|
||||
"doctype": "Newsletter List Subscriber",
|
||||
"email": "test_subscriber1@example.com",
|
||||
"newsletter_list": "_Test Newsletter List"
|
||||
},
|
||||
{
|
||||
"doctype": "Newsletter List Subscriber",
|
||||
"email": "test_subscriber2@example.com",
|
||||
"newsletter_list": "_Test Newsletter List"
|
||||
},
|
||||
{
|
||||
"doctype": "Newsletter List Subscriber",
|
||||
"email": "test_subscriber3@example.com",
|
||||
"newsletter_list": "_Test Newsletter List"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -10,4 +10,4 @@ class NewsletterListSubscriber(Document):
|
||||
pass
|
||||
|
||||
def after_doctype_insert():
|
||||
frappe.db.add_unique("Newsletter List Subscriber", ("name", "email"))
|
||||
frappe.db.add_unique("Newsletter List Subscriber", ("newsletter_list", "email"))
|
||||
|
||||
@@ -5,7 +5,7 @@ app_publisher = "Frappe Technologies Pvt. Ltd. and Contributors"
|
||||
app_description = "Open Source Enterprise Resource Planning for Small and Midsized Organizations"
|
||||
app_icon = "icon-th"
|
||||
app_color = "#e74c3c"
|
||||
app_version = "5.0.3"
|
||||
app_version = "5.0.12"
|
||||
|
||||
error_report_email = "support@erpnext.com"
|
||||
|
||||
@@ -34,13 +34,13 @@ website_context = {
|
||||
|
||||
website_route_rules = [
|
||||
{"from_route": "/orders", "to_route": "Sales Order"},
|
||||
{"from_route": "/orders/<name>", "to_route": "print", "defaults": {"doctype": "Sales Order"}},
|
||||
{"from_route": "/orders/<path:name>", "to_route": "print", "defaults": {"doctype": "Sales Order"}},
|
||||
{"from_route": "/invoices", "to_route": "Sales Invoice"},
|
||||
{"from_route": "/invoices/<name>", "to_route": "print", "defaults": {"doctype": "Sales Invoice"}},
|
||||
{"from_route": "/invoices/<path:name>", "to_route": "print", "defaults": {"doctype": "Sales Invoice"}},
|
||||
{"from_route": "/shipments", "to_route": "Delivery Note"},
|
||||
{"from_route": "/shipments/<name>", "to_route": "print", "defaults": {"doctype": "Delivery Note"}},
|
||||
{"from_route": "/shipments/<path:name>", "to_route": "print", "defaults": {"doctype": "Delivery Note"}},
|
||||
{"from_route": "/issues", "to_route": "Issue"},
|
||||
{"from_route": "/issues/<name>", "to_route": "print", "defaults": {"doctype": "Issue"}},
|
||||
{"from_route": "/issues/<path:name>", "to_route": "print", "defaults": {"doctype": "Issue"}},
|
||||
{"from_route": "/addresses", "to_route": "Address"},
|
||||
]
|
||||
|
||||
@@ -96,8 +96,8 @@ scheduler_events = {
|
||||
]
|
||||
}
|
||||
|
||||
default_mail_footer = """<div style="padding: 7px; margin-top: 7px;">
|
||||
<a style="color: #8D99A6; font-size: 85%; text-decoration: none;" href="https://erpnext.com" target="_blank">
|
||||
default_mail_footer = """<div style="padding: 15px; text-align: center;">
|
||||
<a href="https://erpnext.com?source=via_email_footer" target="_blank" style="color: #8d99a6;">
|
||||
Sent via ERPNext
|
||||
</a>
|
||||
</div>"""
|
||||
|
||||
@@ -12,6 +12,9 @@ class TestSalarySlip(unittest.TestCase):
|
||||
def setUp(self):
|
||||
frappe.db.sql("""delete from `tabLeave Application`""")
|
||||
frappe.db.sql("""delete from `tabSalary Slip`""")
|
||||
|
||||
frappe.db.set_value("Holiday List", "_Test Holiday List", "is_default", 1)
|
||||
|
||||
from erpnext.hr.doctype.leave_application.test_leave_application import _test_records as leave_applications
|
||||
la = frappe.copy_doc(leave_applications[2])
|
||||
la.insert()
|
||||
@@ -26,6 +29,7 @@ class TestSalarySlip(unittest.TestCase):
|
||||
frappe.db.set_value("HR Settings", "HR Settings", "include_holidays_in_total_working_days", 1)
|
||||
ss = frappe.copy_doc(test_records[0])
|
||||
ss.insert()
|
||||
|
||||
self.assertEquals(ss.total_days_in_month, 31)
|
||||
self.assertEquals(ss.payment_days, 30)
|
||||
self.assertEquals(ss.earnings[0].e_modified_amount, 14516.13)
|
||||
@@ -36,8 +40,10 @@ class TestSalarySlip(unittest.TestCase):
|
||||
self.assertEquals(ss.net_pay, 14867.74)
|
||||
|
||||
def test_salary_slip_with_holidays_excluded(self):
|
||||
frappe.db.set_value("HR Settings", "HR Settings", "include_holidays_in_total_working_days", 0)
|
||||
ss = frappe.copy_doc(test_records[0])
|
||||
ss.insert()
|
||||
|
||||
self.assertEquals(ss.total_days_in_month, 30)
|
||||
self.assertEquals(ss.payment_days, 29)
|
||||
self.assertEquals(ss.earnings[0].e_modified_amount, 14500)
|
||||
@@ -102,6 +108,6 @@ class TestSalarySlip(unittest.TestCase):
|
||||
|
||||
return salary_slip
|
||||
|
||||
test_dependencies = ["Leave Application"]
|
||||
test_dependencies = ["Leave Application", "Holiday List"]
|
||||
|
||||
test_records = frappe.get_test_records('Salary Slip')
|
||||
|
||||
@@ -1,27 +1,36 @@
|
||||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
// On REFRESH
|
||||
frappe.provide("erpnext.bom");
|
||||
cur_frm.cscript.refresh = function(doc,dt,dn){
|
||||
cur_frm.toggle_enable("item", doc.__islocal);
|
||||
toggle_operations(cur_frm);
|
||||
|
||||
if (!doc.__islocal && doc.docstatus<2) {
|
||||
cur_frm.add_custom_button(__("Update Cost"), cur_frm.cscript.update_cost);
|
||||
}
|
||||
}
|
||||
frappe.ui.form.on("BOM", {
|
||||
onload_post_render: function(frm) {
|
||||
frm.get_field("items").grid.set_multiple_add("item_code", "qty");
|
||||
},
|
||||
refresh: function(frm) {
|
||||
frm.toggle_enable("item", frm.doc.__islocal);
|
||||
toggle_operations(frm);
|
||||
|
||||
cur_frm.cscript.update_cost = function() {
|
||||
return frappe.call({
|
||||
doc: cur_frm.doc,
|
||||
method: "update_cost",
|
||||
freeze: true,
|
||||
callback: function(r) {
|
||||
if(!r.exc) cur_frm.refresh_fields();
|
||||
if (!frm.doc.__islocal && frm.doc.docstatus<2) {
|
||||
frm.add_custom_button(__("Update Cost"), function() {
|
||||
frm.events.update_cost(frm);
|
||||
});
|
||||
frm.add_custom_button(__("Browse BOM"), function() {
|
||||
frappe.set_route("bom-browser", frm.doc.name);
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
update_cost: function(frm) {
|
||||
return frappe.call({
|
||||
doc: frm.doc,
|
||||
method: "update_cost",
|
||||
freeze: true,
|
||||
callback: function(r) {
|
||||
if(!r.exc) frm.refresh_fields();
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
cur_frm.add_fetch("item", "description", "description");
|
||||
cur_frm.add_fetch("item", "image", "image");
|
||||
@@ -35,7 +44,6 @@ cur_frm.cscript.hour_rate = function(doc, dt, dn) {
|
||||
}
|
||||
|
||||
cur_frm.cscript.time_in_mins = cur_frm.cscript.hour_rate;
|
||||
cur_frm.cscript.fixed_cycle_cost = cur_frm.cscript.hour_rate;
|
||||
|
||||
cur_frm.cscript.item_code = function(doc, cdt, cdn) {
|
||||
get_bom_material_detail(doc, cdt, cdn);
|
||||
|
||||
@@ -10,3 +10,5 @@ frappe.listview_settings['BOM'] = {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
frappe.help.youtube_id["BOM"] = "hDV0c1OeWLo";
|
||||
|
||||
@@ -35,18 +35,20 @@ frappe.ui.form.on("Production Order", "additional_operating_cost", function(frm)
|
||||
|
||||
frappe.ui.form.on("Production Order Operation", "workstation", function(frm, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
frappe.call({
|
||||
"method": "frappe.client.get",
|
||||
args: {
|
||||
doctype: "Workstation",
|
||||
name: d.workstation
|
||||
},
|
||||
callback: function (data) {
|
||||
frappe.model.set_value(d.doctype, d.name, "hour_rate", data.message.hour_rate);
|
||||
erpnext.production_order.calculate_cost(frm.doc);
|
||||
erpnext.production_order.calculate_total_cost(frm);
|
||||
}
|
||||
})
|
||||
if (d.workstation) {
|
||||
frappe.call({
|
||||
"method": "frappe.client.get",
|
||||
args: {
|
||||
doctype: "Workstation",
|
||||
name: d.workstation
|
||||
},
|
||||
callback: function (data) {
|
||||
frappe.model.set_value(d.doctype, d.name, "hour_rate", data.message.hour_rate);
|
||||
erpnext.production_order.calculate_cost(frm.doc);
|
||||
erpnext.production_order.calculate_total_cost(frm);
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
frappe.ui.form.on("Production Order Operation", "time_in_mins", function(frm, cdt, cdn) {
|
||||
|
||||
@@ -176,18 +176,18 @@ class ProductionOrder(Document):
|
||||
self.set('operations', [])
|
||||
|
||||
operations = frappe.db.sql("""select operation, description, workstation, idx,
|
||||
hour_rate, time_in_mins, "Pending" as status from `tabBOM Operation`
|
||||
hour_rate, time_in_mins, "Pending" as status from `tabBOM Operation`
|
||||
where parent = %s order by idx""", self.bom_no, as_dict=1)
|
||||
|
||||
self.set('operations', operations)
|
||||
self.calculate_time()
|
||||
|
||||
|
||||
def calculate_time(self):
|
||||
bom_qty = frappe.db.get_value("BOM", self.bom_no, "quantity")
|
||||
|
||||
|
||||
for d in self.get("operations"):
|
||||
d.time_in_mins = flt(d.time_in_mins) / flt(bom_qty) * flt(self.qty)
|
||||
|
||||
|
||||
self.calculate_operating_cost()
|
||||
|
||||
def get_holidays(self, workstation):
|
||||
@@ -220,7 +220,9 @@ class ProductionOrder(Document):
|
||||
time_log = make_time_log(self.name, d.operation, d.planned_start_time, d.planned_end_time,
|
||||
flt(self.qty) - flt(d.completed_qty), self.project_name, d.workstation, operation_id=d.name)
|
||||
|
||||
self.check_operation_fits_in_working_hours(d)
|
||||
if d.workstation:
|
||||
# validate operating hours if workstation [not mandatory] is specified
|
||||
self.check_operation_fits_in_working_hours(d)
|
||||
|
||||
original_start_time = time_log.from_time
|
||||
while True:
|
||||
|
||||
@@ -130,10 +130,9 @@ class TestProductionOrder(unittest.TestCase):
|
||||
prod_order = make_prod_order_test_record(item="_Test FG Item 2",
|
||||
planned_start_date="2014-11-25 00:00:00", qty=1, do_not_save=True)
|
||||
prod_order.set_production_order_operations()
|
||||
prod_order.save()
|
||||
cost = prod_order.planned_operating_cost
|
||||
prod_order.qty = 2
|
||||
prod_order.save()
|
||||
prod_order.set_production_order_operations()
|
||||
self.assertEqual(prod_order.planned_operating_cost, cost*2)
|
||||
|
||||
def make_prod_order_test_record(**args):
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
"print_hide": 0,
|
||||
"read_only": 1,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
@@ -293,7 +293,7 @@
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"modified": "2015-04-22 03:25:18.542350",
|
||||
"modified": "2015-05-21 13:46:27.730392",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Production Order Operation",
|
||||
|
||||
@@ -359,10 +359,7 @@ class ProductionPlanningTool(Document):
|
||||
|
||||
def insert_purchase_request(self):
|
||||
items_to_be_requested = self.get_requested_items()
|
||||
|
||||
from erpnext.accounts.utils import get_fiscal_year
|
||||
fiscal_year = get_fiscal_year(nowdate())[0]
|
||||
|
||||
|
||||
purchase_request_list = []
|
||||
if items_to_be_requested:
|
||||
for item in items_to_be_requested:
|
||||
@@ -372,7 +369,6 @@ class ProductionPlanningTool(Document):
|
||||
"transaction_date": nowdate(),
|
||||
"status": "Draft",
|
||||
"company": self.company,
|
||||
"fiscal_year": fiscal_year,
|
||||
"requested_by": frappe.session.user,
|
||||
"material_request_type": "Purchase"
|
||||
})
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.utils import flt, cint, getdate, formatdate, comma_and, time_diff_in_seconds, get_datetime
|
||||
from frappe.utils import flt, cint, getdate, formatdate, comma_and, time_diff_in_seconds, to_timedelta
|
||||
from frappe.model.document import Document
|
||||
from dateutil.parser import parse
|
||||
|
||||
@@ -60,7 +60,7 @@ def is_within_operating_hours(workstation, operation, from_datetime, to_datetime
|
||||
workstation = frappe.get_doc("Workstation", workstation)
|
||||
|
||||
for working_hour in workstation.working_hours:
|
||||
slot_length = (get_datetime(working_hour.end_time) - get_datetime(working_hour.start_time)).total_seconds()
|
||||
slot_length = (to_timedelta(working_hour.end_time or "") - to_timedelta(working_hour.start_time or "")).total_seconds()
|
||||
if slot_length >= operation_length:
|
||||
return
|
||||
|
||||
|
||||
0
erpnext/manufacturing/page/__init__.py
Normal file
0
erpnext/manufacturing/page/__init__.py
Normal file
0
erpnext/manufacturing/page/bom_browser/__init__.py
Normal file
0
erpnext/manufacturing/page/bom_browser/__init__.py
Normal file
90
erpnext/manufacturing/page/bom_browser/bom_browser.js
Normal file
90
erpnext/manufacturing/page/bom_browser/bom_browser.js
Normal file
@@ -0,0 +1,90 @@
|
||||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
frappe.pages['bom-browser'].on_page_load = function(wrapper) {
|
||||
var page = frappe.ui.make_app_page({
|
||||
parent: wrapper,
|
||||
title: 'BOM Browser',
|
||||
single_column: true
|
||||
});
|
||||
|
||||
page.main.css({
|
||||
"min-height": "300px",
|
||||
"padding-bottom": "25px"
|
||||
});
|
||||
|
||||
page.tree_area = $('<div class="padding"><p class="text-muted">'+
|
||||
__("Select BOM to start")
|
||||
+'</p></div>').appendTo(page.main);
|
||||
|
||||
frappe.breadcrumbs.add(frappe.breadcrumbs.last_module || "Manufacturing");
|
||||
|
||||
var make_tree = function() {
|
||||
erpnext.bom_tree = new erpnext.BOMTree(page.$bom_select.val(), page, page.tree_area);
|
||||
}
|
||||
|
||||
page.$bom_select = wrapper.page.add_field({fieldname: "bom",
|
||||
fieldtype:"Link", options: "BOM", label: __("BOM")}).$input
|
||||
.change(function() {
|
||||
make_tree();
|
||||
});
|
||||
|
||||
page.set_secondary_action(__('Refresh'), function() {
|
||||
make_tree();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
frappe.pages['bom-browser'].on_page_show = function(wrapper){
|
||||
// set from route
|
||||
var bom = null;
|
||||
if(frappe.get_route()[1]) {
|
||||
var bom = frappe.get_route().splice(1).join("/");
|
||||
}
|
||||
if(frappe.route_options && frappe.route_options.bom) {
|
||||
var bom = frappe.route_options.bom;
|
||||
}
|
||||
if(bom) {
|
||||
wrapper.page.$bom_select.val(bom).trigger("change");
|
||||
}
|
||||
};
|
||||
|
||||
erpnext.BOMTree = Class.extend({
|
||||
init: function(root, page, parent) {
|
||||
$(parent).empty();
|
||||
var me = this;
|
||||
me.page = page;
|
||||
me.bom = page.$bom_select.val();
|
||||
me.can_read = frappe.model.can_read("BOM");
|
||||
me.can_create = frappe.boot.user.can_create.indexOf("BOM") !== -1 ||
|
||||
frappe.boot.user.in_create.indexOf("BOM") !== -1;
|
||||
me.can_write = frappe.model.can_write("BOM");
|
||||
me.can_delete = frappe.model.can_delete("BOM");
|
||||
|
||||
this.tree = new frappe.ui.Tree({
|
||||
parent: $(parent),
|
||||
label: me.bom,
|
||||
args: {parent: me.bom},
|
||||
method: 'erpnext.manufacturing.page.bom_browser.bom_browser.get_children',
|
||||
toolbar: [
|
||||
{toggle_btn: true},
|
||||
{
|
||||
label:__("Edit"),
|
||||
condition: function(node) {
|
||||
return node.expandable;
|
||||
},
|
||||
click: function(node) {
|
||||
frappe.set_route("Form", "BOM", node.data.parent);
|
||||
}
|
||||
}
|
||||
],
|
||||
get_label: function(node) {
|
||||
if(node.data.qty) {
|
||||
return node.data.qty + " x " + node.data.value;
|
||||
} else {
|
||||
return node.data.value;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
21
erpnext/manufacturing/page/bom_browser/bom_browser.json
Normal file
21
erpnext/manufacturing/page/bom_browser/bom_browser.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"content": null,
|
||||
"creation": "2015-05-25 02:57:33.472044",
|
||||
"docstatus": 0,
|
||||
"doctype": "Page",
|
||||
"modified": "2015-05-25 02:57:33.472044",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "bom-browser",
|
||||
"owner": "Administrator",
|
||||
"page_name": "bom-browser",
|
||||
"roles": [
|
||||
{
|
||||
"role": "Manufacturing User"
|
||||
}
|
||||
],
|
||||
"script": null,
|
||||
"standard": "Yes",
|
||||
"style": null,
|
||||
"title": "BOM Browser"
|
||||
}
|
||||
15
erpnext/manufacturing/page/bom_browser/bom_browser.py
Normal file
15
erpnext/manufacturing/page/bom_browser/bom_browser.py
Normal file
@@ -0,0 +1,15 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_children(parent):
|
||||
return frappe.db.sql("""select item_code as value,
|
||||
bom_no as parent, qty,
|
||||
if(ifnull(bom_no, "")!="", 1, 0) as expandable
|
||||
from `tabBOM Item`
|
||||
where parent=%s
|
||||
order by idx
|
||||
""", parent, as_dict=True)
|
||||
@@ -155,3 +155,9 @@ erpnext.patches.v5_0.reclculate_planned_operating_cost_in_production_order
|
||||
erpnext.patches.v5_0.repost_requested_qty
|
||||
erpnext.patches.v5_0.fix_taxes_and_totals_in_party_currency
|
||||
erpnext.patches.v5_0.update_tax_amount_after_discount_in_purchase_cycle
|
||||
erpnext.patches.v5_0.rename_pos_setting
|
||||
erpnext.patches.v5_0.update_operation_description
|
||||
erpnext.patches.v5_0.set_footer_address
|
||||
execute:frappe.db.set_value("Backup Manager", None, "send_backups_to_dropbox", 1 if frappe.db.get_value("Backup Manager", None, "upload_backups_to_dropbox") in ("Daily", "Weekly") else 0)
|
||||
execute:frappe.db.sql_list("delete from `tabDocPerm` where parent='Issue' and modified_by='Administrator' and role='Guest'")
|
||||
erpnext.patches.v5_0.update_item_and_description_again
|
||||
|
||||
@@ -19,20 +19,21 @@ def create_receivable_payable_account():
|
||||
receivable_payable_accounts = frappe._dict()
|
||||
|
||||
def _create_account(args):
|
||||
account_id = frappe.db.get_value("Account",
|
||||
{"account_name": args["account_name"], "company": args["company"]})
|
||||
if not account_id:
|
||||
account = frappe.new_doc("Account")
|
||||
account.is_group = 0
|
||||
account.update(args)
|
||||
account.insert()
|
||||
if args["parent_account"] and frappe.db.exists("Account", args["parent_account"]):
|
||||
account_id = frappe.db.get_value("Account",
|
||||
{"account_name": args["account_name"], "company": args["company"]})
|
||||
if not account_id:
|
||||
account = frappe.new_doc("Account")
|
||||
account.is_group = 0
|
||||
account.update(args)
|
||||
account.insert()
|
||||
|
||||
account_id = account.name
|
||||
account_id = account.name
|
||||
|
||||
frappe.db.set_value("Company", args["company"], ("default_receivable_account"
|
||||
if args["account_type"]=="Receivable" else "default_payable_account"), account_id)
|
||||
frappe.db.set_value("Company", args["company"], ("default_receivable_account"
|
||||
if args["account_type"]=="Receivable" else "default_payable_account"), account_id)
|
||||
|
||||
receivable_payable_accounts.setdefault(args["company"], {}).setdefault(args["account_type"], account_id)
|
||||
receivable_payable_accounts.setdefault(args["company"], {}).setdefault(args["account_type"], account_id)
|
||||
|
||||
for company in frappe.db.sql_list("select name from tabCompany"):
|
||||
_create_account({
|
||||
@@ -96,15 +97,16 @@ def set_party_in_jv_and_gl_entry(receivable_payable_accounts):
|
||||
frappe.db.commit()
|
||||
|
||||
def delete_individual_party_account():
|
||||
frappe.db.sql("""delete from `tabAccount` acc
|
||||
where ifnull(acc.master_type, '') in ('Customer', 'Supplier')
|
||||
and ifnull(acc.master_name, '') != ''
|
||||
and not exists(select gle.name from `tabGL Entry` gle where gle.account = acc.name)""")
|
||||
frappe.db.sql("""delete from `tabAccount`
|
||||
where ifnull(master_type, '') in ('Customer', 'Supplier')
|
||||
and ifnull(master_name, '') != ''
|
||||
and not exists(select gle.name from `tabGL Entry` gle
|
||||
where gle.account = tabAccount.name)""")
|
||||
|
||||
accounts_not_deleted = frappe.db.sql_list("""select name from `tabAccount` acc
|
||||
where ifnull(acc.master_type, '') in ('Customer', 'Supplier')
|
||||
and ifnull(acc.master_name, '') != ''
|
||||
and exists(select gle.name from `tabGL Entry` gle where gle.account = acc.name)""")
|
||||
accounts_not_deleted = frappe.db.sql_list("""select tabAccount.name from `tabAccount`
|
||||
where ifnull(master_type, '') in ('Customer', 'Supplier')
|
||||
and ifnull(master_name, '') != ''
|
||||
and exists(select gle.name from `tabGL Entry` gle where gle.account = tabAccount.name)""")
|
||||
|
||||
if accounts_not_deleted:
|
||||
print "Accounts not deleted: " + "\n".join(accounts_not_deleted)
|
||||
|
||||
5
erpnext/patches/v5_0/rename_pos_setting.py
Normal file
5
erpnext/patches/v5_0/rename_pos_setting.py
Normal file
@@ -0,0 +1,5 @@
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
if frappe.db.table_exists("POS Setting"):
|
||||
frappe.rename_doc("DocType", "POS Setting", "POS Profile")
|
||||
@@ -46,9 +46,9 @@ def get_all_renamed_fields():
|
||||
)
|
||||
|
||||
for fields in rename_map.values():
|
||||
if fields[0] != "entries":
|
||||
renamed_fields += tuple(fields)
|
||||
|
||||
valid_fields = [d for d in fields if d[0] != "entries"]
|
||||
renamed_fields += tuple(valid_fields)
|
||||
|
||||
return renamed_fields
|
||||
|
||||
def update_script(dt, name, script_field, script, renamed_fields):
|
||||
@@ -62,4 +62,4 @@ def update_script(dt, name, script_field, script, renamed_fields):
|
||||
elif dt in ("Sales Invoice", "Purchase Invoice"):
|
||||
script = re.sub(r"\bentries\b", "items", script)
|
||||
|
||||
frappe.db.set_value(dt, name, script_field, script)
|
||||
frappe.db.set_value(dt, name, script_field, script)
|
||||
8
erpnext/patches/v5_0/set_footer_address.py
Normal file
8
erpnext/patches/v5_0/set_footer_address.py
Normal file
@@ -0,0 +1,8 @@
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
frappe.reload_doctype("System Settings")
|
||||
ss = frappe.get_doc("System Settings", "System Settings")
|
||||
ss.email_footer_address = frappe.db.get_default("company")
|
||||
ss.flags.ignore_mandatory = True
|
||||
ss.save()
|
||||
49
erpnext/patches/v5_0/update_item_and_description_again.py
Normal file
49
erpnext/patches/v5_0/update_item_and_description_again.py
Normal file
@@ -0,0 +1,49 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
import frappe
|
||||
from frappe.utils import cstr
|
||||
import re
|
||||
|
||||
def execute():
|
||||
item_details = frappe._dict()
|
||||
for d in frappe.db.sql("select name, description from `tabItem`", as_dict=1):
|
||||
description = cstr(d.description).strip()
|
||||
new_desc = extract_description(description)
|
||||
|
||||
item_details.setdefault(d.name, frappe._dict({
|
||||
"old_description": description,
|
||||
"new_description": new_desc
|
||||
}))
|
||||
|
||||
|
||||
dt_list= ["Purchase Order Item","Supplier Quotation Item", "BOM", "BOM Explosion Item" , \
|
||||
"BOM Item", "Opportunity Item" , "Quotation Item" , "Sales Order Item" , "Delivery Note Item" , \
|
||||
"Material Request Item" , "Purchase Receipt Item" , "Stock Entry Detail"]
|
||||
for dt in dt_list:
|
||||
frappe.reload_doctype(dt)
|
||||
records = frappe.db.sql("""select name, `{0}` as item_code, description from `tab{1}`
|
||||
where description is not null and description like '%%<table%%'"""
|
||||
.format("item" if dt=="BOM" else "item_code", dt), as_dict=1)
|
||||
|
||||
count = 1
|
||||
for d in records:
|
||||
if d.item_code and item_details.get(d.item_code) \
|
||||
and cstr(d.description) == item_details.get(d.item_code).old_description:
|
||||
desc = item_details.get(d.item_code).new_description
|
||||
else:
|
||||
desc = extract_description(cstr(d.description))
|
||||
|
||||
frappe.db.sql("""update `tab{0}` set description = %s
|
||||
where name = %s """.format(dt), (desc, d.name))
|
||||
|
||||
count += 1
|
||||
if count % 500 == 0:
|
||||
frappe.db.commit()
|
||||
|
||||
|
||||
def extract_description(desc):
|
||||
for tag in ("img", "table", "tr", "td"):
|
||||
desc = re.sub("\</*{0}[^>]*\>".format(tag), "", desc)
|
||||
|
||||
return desc
|
||||
@@ -11,23 +11,23 @@ def execute():
|
||||
for d in frappe.db.sql("select name, description_html, description from `tabItem`", as_dict=1):
|
||||
description = cstr(d.description_html).strip() or cstr(d.description).strip()
|
||||
image_url, new_desc = extract_image_and_description(description)
|
||||
|
||||
|
||||
item_details.setdefault(d.name, frappe._dict({
|
||||
"old_description": description,
|
||||
"new_description": new_desc,
|
||||
"image_url": image_url
|
||||
}))
|
||||
|
||||
|
||||
|
||||
|
||||
dt_list= ["Purchase Order Item","Supplier Quotation Item", "BOM", "BOM Explosion Item" , \
|
||||
"BOM Item", "Opportunity Item" , "Quotation Item" , "Sales Order Item" , "Delivery Note Item" , \
|
||||
"Material Request Item" , "Purchase Receipt Item" , "Stock Entry Detail"]
|
||||
for dt in dt_list:
|
||||
frappe.reload_doctype(dt)
|
||||
records = frappe.db.sql("""select name, `{0}` as item_code, description from `tab{1}`
|
||||
records = frappe.db.sql("""select name, `{0}` as item_code, description from `tab{1}`
|
||||
where description is not null and image is null and description like '%%<img%%'"""
|
||||
.format("item" if dt=="BOM" else "item_code", dt), as_dict=1)
|
||||
|
||||
|
||||
count = 1
|
||||
for d in records:
|
||||
if d.item_code and item_details.get(d.item_code) \
|
||||
@@ -40,7 +40,7 @@ def execute():
|
||||
if image_url:
|
||||
frappe.db.sql("""update `tab{0}` set description = %s, image = %s
|
||||
where name = %s """.format(dt), (desc, image_url, d.name))
|
||||
|
||||
|
||||
count += 1
|
||||
if count % 500 == 0:
|
||||
frappe.db.commit()
|
||||
@@ -49,5 +49,5 @@ def execute():
|
||||
def extract_image_and_description(data):
|
||||
image_url = find_first_image(data)
|
||||
desc = re.sub("\<img[^>]+\>", "", data)
|
||||
|
||||
return image_url, desc
|
||||
|
||||
return image_url, desc
|
||||
|
||||
10
erpnext/patches/v5_0/update_operation_description.py
Normal file
10
erpnext/patches/v5_0/update_operation_description.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
import frappe
|
||||
import frappe.permissions
|
||||
|
||||
def execute():
|
||||
if "opn_description" in frappe.db.get_table_columns("BOM Operation"):
|
||||
frappe.db.sql("""update `tabBOM Operation` set description = opn_description
|
||||
where ifnull(description, '') = ''""")
|
||||
@@ -10,13 +10,15 @@ def execute():
|
||||
for m in frappe.get_all("Project Milestone", "*"):
|
||||
if (m.milestone and m.milestone_date
|
||||
and frappe.db.exists("Project", m.parent)):
|
||||
frappe.get_doc({
|
||||
task = frappe.get_doc({
|
||||
"doctype": "Task",
|
||||
"subject": m.milestone,
|
||||
"expected_start_date": m.milestone_date,
|
||||
"status": "Open" if m.status=="Pending" else "Closed",
|
||||
"project": m.parent,
|
||||
}).insert(ignore_permissions=True)
|
||||
})
|
||||
task.flags.ignore_mandatory = True
|
||||
task.insert(ignore_permissions=True)
|
||||
|
||||
# remove project milestone
|
||||
frappe.delete_doc("DocType", "Project Milestone")
|
||||
|
||||
@@ -48,3 +48,9 @@
|
||||
.product-text {
|
||||
padding: 15px 0px;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.product-search {
|
||||
width: 100%;
|
||||
margin-bottom: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 516 B |
BIN
erpnext/public/images/erpnext-footer.png
Normal file
BIN
erpnext/public/images/erpnext-footer.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
@@ -1,112 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
viewBox="0 0 680 820"
|
||||
preserveAspectRatio="xMidyMid meet"
|
||||
width="100%"
|
||||
height="100%">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
style="display:inline">
|
||||
<rect
|
||||
style="fill:#fff"
|
||||
id="rect3800"
|
||||
width="150"
|
||||
height="150"
|
||||
x="60.000008"
|
||||
y="-472.36218"
|
||||
rx="20"
|
||||
ry="20"
|
||||
transform="scale(1,-1)" />
|
||||
</g>
|
||||
<g
|
||||
id="layer2">
|
||||
<path
|
||||
transform="scale(1,-1)"
|
||||
style="display:inline;fill:#fff"
|
||||
d="m 180,-372.36218 110,0 20,0 0,20 0,110 c 0,11.08 -8.92,20 -20,20 l -110,0 c -11.08,0 -20,-8.92 -20,-20 l 0,-110 c 0,-11.08 8.92,-20 20,-20 z"
|
||||
id="rect3051"/>
|
||||
</g>
|
||||
<g
|
||||
id="layer3">
|
||||
<rect
|
||||
style="display:inline;fill:#fff"
|
||||
id="rect3840"
|
||||
width="150"
|
||||
height="150"
|
||||
x="260"
|
||||
y="-272.36218"
|
||||
rx="20"
|
||||
ry="20"
|
||||
transform="scale(1,-1)" />
|
||||
</g>
|
||||
<g
|
||||
id="layer4">
|
||||
<path
|
||||
id="path3054"
|
||||
d="m 490,372.36218 -110,0 -20,0 0,-20 0,-110 c 0,-11.08 8.92,-20 20,-20 l 110,0 c 11.08,0 20,8.92 20,20 l 0,110 c 0,11.08 -8.92,20 -20,20 z"
|
||||
style="display:inline;fill:#fff" />
|
||||
</g>
|
||||
<g
|
||||
id="layer5">
|
||||
<rect
|
||||
style="display:inline;fill:#fff"
|
||||
id="rect3844"
|
||||
width="150"
|
||||
height="150"
|
||||
x="460"
|
||||
y="-472.36218"
|
||||
rx="20"
|
||||
ry="20"
|
||||
transform="scale(1,-1)" />
|
||||
</g>
|
||||
<g
|
||||
id="layer6">
|
||||
<path
|
||||
style="display:inline;fill:#fff"
|
||||
d="m 490,422.36218 -110,0 -20,0 0,20 0,110 c 0,11.08 8.92,20 20,20 l 110,0 c 11.08,0 20,-8.92 20,-20 l 0,-110 c 0,-11.08 -8.92,-20 -20,-20 z"
|
||||
id="path3058" />
|
||||
</g>
|
||||
<g
|
||||
id="layer7">
|
||||
<rect
|
||||
style="display:inline;fill:#fff"
|
||||
id="rect3848"
|
||||
width="150"
|
||||
height="150"
|
||||
x="260"
|
||||
y="-672.36218"
|
||||
rx="20"
|
||||
ry="20"
|
||||
transform="scale(1,-1)" />
|
||||
</g>
|
||||
<g
|
||||
id="layer8">
|
||||
<path
|
||||
id="path3056"
|
||||
d="m 180,422.36218 110,0 20,0 0,20 0,110 c 0,11.08 -8.92,20 -20,20 l -110,0 c -11.08,0 -20,-8.92 -20,-20 l 0,-110 c 0,-11.08 8.92,-20 20,-20 z"
|
||||
style="display:inline;fill:#fff" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 429 B |
Binary file not shown.
|
Before Width: | Height: | Size: 691 B |
@@ -66,18 +66,22 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
|
||||
apply_default_taxes: function() {
|
||||
var me = this;
|
||||
return frappe.call({
|
||||
method: "erpnext.controllers.accounts_controller.get_default_taxes_and_charges",
|
||||
args: {
|
||||
"master_doctype": frappe.meta.get_docfield(me.frm.doc.doctype, "taxes_and_charges",
|
||||
me.frm.doc.name).options
|
||||
},
|
||||
callback: function(r) {
|
||||
if(!r.exc) {
|
||||
me.frm.set_value("taxes", r.message);
|
||||
var taxes_and_charges_field = frappe.meta.get_docfield(me.frm.doc.doctype, "taxes_and_charges",
|
||||
me.frm.doc.name);
|
||||
|
||||
if(taxes_and_charges_field) {
|
||||
frappe.call({
|
||||
method: "erpnext.controllers.accounts_controller.get_default_taxes_and_charges",
|
||||
args: {
|
||||
"master_doctype": taxes_and_charges_field.options
|
||||
},
|
||||
callback: function(r) {
|
||||
if(!r.exc) {
|
||||
me.frm.set_value("taxes", r.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
setup_sms: function() {
|
||||
@@ -94,7 +98,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
},
|
||||
|
||||
hide_currency_and_price_list: function() {
|
||||
if(this.frm.doc.docstatus > 0) {
|
||||
if(this.frm.doc.conversion_rate == 1 && this.frm.doc.docstatus > 0) {
|
||||
hide_field("currency_and_price_list");
|
||||
} else {
|
||||
unhide_field("currency_and_price_list");
|
||||
@@ -205,9 +209,11 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
me.frm.set_value('plc_conversion_rate', 1.0);
|
||||
}
|
||||
if (company_doc.default_letter_head) {
|
||||
me.frm.set_value("letter_head", company_doc.default_letter_head);
|
||||
if(me.frm.fields_dict.letter_head) {
|
||||
me.frm.set_value("letter_head", company_doc.default_letter_head);
|
||||
}
|
||||
}
|
||||
if (company_doc.default_terms) {
|
||||
if (company_doc.default_terms && me.frm.doc.doctype != "Purchase Invoice") {
|
||||
me.frm.set_value("tc_name", company_doc.default_terms);
|
||||
}
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ erpnext.feature_setup.feature_dict = {
|
||||
'base_total', 'base_net_total', 'base_discount_amount', 'base_total_taxes_and_charges'],
|
||||
'items': ['base_price_list_rate','base_amount','base_rate', 'base_net_rate', 'base_net_amount']
|
||||
},
|
||||
'POS Setting': {'fields':['conversion_rate','currency']},
|
||||
'POS Profile': {'fields':['conversion_rate','currency']},
|
||||
'Quotation': {
|
||||
'fields': ['conversion_rate','currency','base_grand_total','base_in_words','base_rounded_total',
|
||||
'base_total', 'base_net_total', 'base_discount_amount', 'base_total_taxes_and_charges'],
|
||||
|
||||
@@ -331,7 +331,7 @@ erpnext.pos.PointOfSale = Class.extend({
|
||||
},
|
||||
set_primary_action: function() {
|
||||
var me = this;
|
||||
if (!this.frm.pos_active) return;
|
||||
if (this.frm.page.current_view_name==="main") return;
|
||||
|
||||
if (this.frm.doctype == "Sales Invoice" && this.frm.doc.docstatus===0) {
|
||||
if (!this.frm.doc.is_pos) {
|
||||
@@ -342,7 +342,6 @@ erpnext.pos.PointOfSale = Class.extend({
|
||||
});
|
||||
} else if (this.frm.doc.docstatus===1) {
|
||||
this.frm.page.set_primary_action(__("New"), function() {
|
||||
me.frm.pos_active = false;
|
||||
erpnext.open_as_pos = true;
|
||||
new_doc(me.frm.doctype);
|
||||
});
|
||||
@@ -464,7 +463,6 @@ erpnext.pos.PointOfSale = Class.extend({
|
||||
var me = this;
|
||||
dialog.set_primary_action(__("Pay"), function() {
|
||||
var values = dialog.get_values();
|
||||
console.log(values);
|
||||
var is_cash = values.mode_of_payment === __("Cash");
|
||||
if (!is_cash) {
|
||||
values.write_off_amount = values.change = 0.0;
|
||||
@@ -498,8 +496,8 @@ erpnext.pos.make_pos_btn = function(frm) {
|
||||
erpnext.pos.toggle(frm) });
|
||||
}
|
||||
|
||||
if(erpnext.open_as_pos && !frm.pos_active) {
|
||||
erpnext.pos.toggle(frm);
|
||||
if(erpnext.open_as_pos && frm.page.current_view_name !== "pos") {
|
||||
erpnext.pos.toggle(frm, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -508,12 +506,22 @@ erpnext.pos.toggle = function(frm, show) {
|
||||
var price_list = frappe.meta.has_field(cur_frm.doc.doctype, "selling_price_list") ?
|
||||
frm.doc.selling_price_list : frm.doc.buying_price_list;
|
||||
|
||||
if((show===true && frm.pos_active) || (show===false && !frm.pos_active)) {
|
||||
return;
|
||||
if(show!==undefined) {
|
||||
if((show===true && frm.page.current_view_name === "pos")
|
||||
|| (show===false && frm.page.current_view_name === "main")) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(show && !price_list) {
|
||||
frappe.throw(__("Please select Price List"));
|
||||
if(frm.page.current_view_name!=="pos") {
|
||||
// before switching, ask for pos name
|
||||
if(!price_list) {
|
||||
frappe.throw(__("Please select Price List"));
|
||||
}
|
||||
|
||||
if(!frm.doc.company) {
|
||||
frappe.throw(__("Please select Company"));
|
||||
}
|
||||
}
|
||||
|
||||
// make pos
|
||||
@@ -523,14 +531,13 @@ erpnext.pos.toggle = function(frm, show) {
|
||||
}
|
||||
|
||||
// toggle view
|
||||
frm.page.set_view(frm.pos_active ? "main" : "pos");
|
||||
frm.pos_active = !frm.pos_active;
|
||||
frm.page.set_view(frm.page.current_view_name==="pos" ? "main" : "pos");
|
||||
|
||||
frm.toolbar.current_status = null;
|
||||
frm.refresh();
|
||||
|
||||
// refresh
|
||||
if(frm.pos_active) {
|
||||
if(frm.page.current_view_name==="pos") {
|
||||
frm.pos.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
</div>
|
||||
{% if(actual_qty != null) { %}
|
||||
<div style="margin-top: 5px;" class="text-muted small text-right">
|
||||
<span title="{%= __("In Stock") %}">{%= actual_qty %}<span>
|
||||
<span title="{%= __("Projected") %}">({%= projected_qty %})<span>
|
||||
<span title="{%= __("In Stock") %}">{%= actual_qty || 0 %}<span>
|
||||
<span title="{%= __("Projected") %}">({%= projected_qty || 0 %})<span>
|
||||
</div>
|
||||
{% } %}
|
||||
</div>
|
||||
|
||||
@@ -14,19 +14,21 @@ $.extend(erpnext, {
|
||||
},
|
||||
|
||||
get_fiscal_year: function(company, date, fn) {
|
||||
frappe.call({
|
||||
type:"GET",
|
||||
method: "erpnext.accounts.utils.get_fiscal_year",
|
||||
args: {
|
||||
"company": company,
|
||||
"date": date,
|
||||
"verbose": 0
|
||||
},
|
||||
callback: function(r) {
|
||||
if (r.message) cur_frm.set_value("fiscal_year", r.message[0]);
|
||||
if (fn) fn();
|
||||
}
|
||||
});
|
||||
if(frappe.meta.get_docfield(cur_frm.doctype, "fiscal_year")) {
|
||||
frappe.call({
|
||||
type:"GET",
|
||||
method: "erpnext.accounts.utils.get_fiscal_year",
|
||||
args: {
|
||||
"company": company,
|
||||
"date": date,
|
||||
"verbose": 0
|
||||
},
|
||||
callback: function(r) {
|
||||
if (r.message) cur_frm.set_value("fiscal_year", r.message[0]);
|
||||
if (fn) fn();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
toggle_naming_series: function() {
|
||||
@@ -130,4 +132,17 @@ $.extend(erpnext.utils, {
|
||||
);
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// add description on posting time
|
||||
$(document).on('app_ready', function() {
|
||||
if(!frappe.datetime.is_timezone_same()) {
|
||||
$.each(["Stock Reconciliation", "Stock Entry", "Stock Ledger Entry",
|
||||
"Delivery Note", "Purchase Receipt", "Sales Invoice"], function(i, d) {
|
||||
frappe.ui.form.on(d, "onload", function(frm) {
|
||||
cur_frm.set_df_property("posting_time", "description",
|
||||
sys_defaults.time_zone);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -15,5 +15,15 @@ frappe.send_message = function(opts, btn) {
|
||||
});
|
||||
};
|
||||
|
||||
erpnext.subscribe_to_newsletter = function(opts, btn) {
|
||||
return frappe.call({
|
||||
type: "POST",
|
||||
method: "erpnext.crm.doctype.newsletter.newsletter.subscribe",
|
||||
btn: btn,
|
||||
args: {"email": opts.email},
|
||||
callback: opts.callback
|
||||
});
|
||||
}
|
||||
|
||||
// for backward compatibility
|
||||
erpnext.send_message = frappe.send_message;
|
||||
erpnext.send_message = frappe.send_message;
|
||||
|
||||
@@ -51,3 +51,10 @@
|
||||
.product-text {
|
||||
padding: 15px 0px;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.product-search {
|
||||
width: 100%;
|
||||
margin-bottom: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,9 @@ class TestCustomer(unittest.TestCase):
|
||||
|
||||
make_test_records("Address")
|
||||
make_test_records("Contact")
|
||||
|
||||
frappe.db.set_value("Contact", "_Test Contact For _Test Customer-_Test Customer",
|
||||
"is_primary_contact", 1)
|
||||
|
||||
details = get_party_details("_Test Customer")
|
||||
|
||||
for key, value in to_check.iteritems():
|
||||
|
||||
@@ -34,8 +34,7 @@ erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({
|
||||
method: "erpnext.crm.doctype.opportunity.opportunity.make_quotation",
|
||||
source_doctype: "Opportunity",
|
||||
get_query_filters: {
|
||||
docstatus: 1,
|
||||
status: "Submitted",
|
||||
status: ["not in", ["Lost", "Closed"]],
|
||||
enquiry_type: cur_frm.doc.order_type,
|
||||
customer: cur_frm.doc.customer || undefined,
|
||||
lead: cur_frm.doc.lead || undefined,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -121,10 +121,11 @@
|
||||
"width": "100px"
|
||||
},
|
||||
{
|
||||
"depends_on": "price_list_rate",
|
||||
"fieldname": "discount_percentage",
|
||||
"fieldtype": "Percent",
|
||||
"in_list_view": 1,
|
||||
"label": "Discount (%)",
|
||||
"label": "Discount on Price List Rate (%)",
|
||||
"oldfieldname": "adj_rate",
|
||||
"oldfieldtype": "Float",
|
||||
"permlevel": 0,
|
||||
@@ -389,7 +390,7 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2015-05-14 14:51:21.557189",
|
||||
"modified": "2015-05-27 02:47:15.474119",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Quotation Item",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user