Compare commits

..

91 Commits

Author SHA1 Message Date
Saurabh
6c3289dbcd Merge branch 'hotfix' 2018-01-24 11:22:54 +05:30
Saurabh
381d452b78 bumped to version 10.0.14 2018-01-24 11:52:53 +06:00
Saurabh
769874d0e9 Merge pull request #12628 from saurabh6790/enable_rename_option
[fix] enable rename for payment terms and payment term template
2018-01-24 11:15:53 +05:30
Saurabh
6cc10104f0 [fix] enable rename for payment terms and payment term template 2018-01-24 11:15:02 +05:30
Saurabh
5b67f4d953 Merge pull request #12626 from saurabh6790/item_price_stock_report_fix
[fix] If buying or selling price list not found, return empty dict
2018-01-24 10:55:51 +05:30
Saurabh
4b9a55b0ef [fix] If buying or selling price list not found, return empty dict 2018-01-24 07:48:56 +05:30
Saurabh
c8399fd093 Merge pull request #12614 from rohitwaghchaure/removed_set_only_once_for_batch_serialno
Disabled property set only once for has serial no and has batch no field in item doctype
2018-01-23 18:08:56 +05:30
Rohit Waghchaure
266e66cd1b Disabled property set only once for has serial no and has batch no field in item doctype 2018-01-23 18:06:12 +05:30
rohitwaghchaure
f3a452850e Merge pull request #12617 from saurabh6790/ux_fix
parse value before setting it to dissable_rounded_total on Purchase Invoice
2018-01-23 17:35:16 +05:30
Saurabh
57df096725 Merge pull request #12600 from vishdha/allow_rename
[new] Allow Rename and Member link with user
2018-01-23 16:49:48 +05:30
Saurabh
db2d02a3e3 Merge pull request #12618 from shreyashah115/warehouse-list
Disabled field in list view - Warehouse DocType
2018-01-23 16:48:59 +05:30
Shreya
dfae11bcee disabled warehouse in list view 2018-01-23 16:46:24 +05:30
rohitwaghchaure
d78e6e04ea Run country fixtures if country changed in the company (#12494) 2018-01-23 15:42:46 +05:30
Saurabh
3959aeb848 [fix] parse value before setting it to dissable_rounded_total on Purchase Invoice 2018-01-23 15:40:43 +05:30
rohitwaghchaure
51293390e4 Merge pull request #12611 from shreyashah115/fetch-conversion-factor
[Fix] Fetch uom conversion factor in material request
2018-01-23 12:41:01 +05:30
rohitwaghchaure
63f4da4402 Merge pull request #12612 from shreyashah115/fix-validation
Fix validation message for overbilling
2018-01-23 12:35:37 +05:30
Shreya
a137fe82a1 fix error message 2018-01-23 11:00:58 +05:30
Shreya
e2b31085a7 fetch uom conversion factor in material request 2018-01-23 10:54:23 +05:30
Vishal
a54815fd9d [new] Allow Rename and Member link with user 2018-01-22 16:02:45 +05:30
Saurabh
4f927ac3e8 Merge branch 'hotfix' 2018-01-22 15:29:14 +05:30
Saurabh
b9f678b350 bumped to version 10.0.13 2018-01-22 15:59:14 +06:00
Saurabh
fb4caff0b2 Merge pull request #12573 from rohitwaghchaure/reorder_issue
[Fix] Wrong projected qty for warehouse group in the process of reorder item, which making extra material requests
2018-01-22 16:49:54 +07:00
Saurabh
e72915847c Merge pull request #12570 from rohitwaghchaure/currency_in_balance_column
Added currency in balance column in general ledger print
2018-01-22 16:35:37 +07:00
rohitwaghchaure
1d93bd50eb Merge pull request #12585 from rohitwaghchaure/sales_income_account_issue
[Fix] Income account can not be group
2018-01-22 15:04:46 +05:30
rohitwaghchaure
8e998875a5 Merge pull request #12590 from shreyashah115/total-on-items-remove
[Fix] Calculate taxes when shipping rule not present at removal of item
2018-01-22 15:03:11 +05:30
rohitwaghchaure
c87a3370cd Merge pull request #12595 from rohitwaghchaure/image_path_in_item_search
[Fix] Image path showing in the item link
2018-01-22 15:01:58 +05:30
Rohit Waghchaure
c4c2bf0bfb [Fix] Image patch showing in the item link 2018-01-22 13:47:28 +05:30
Shreya
39adc8f85f calculate total when items are removed 2018-01-22 13:08:05 +05:30
Rohit Waghchaure
8676590cfe [Fix] Income account can not be group 2018-01-22 12:35:36 +05:30
rohitwaghchaure
cf7b6511ba Merge pull request #12574 from rohitwaghchaure/sales_payment_summary_issue
[Fix] Sales payment summary issue
2018-01-20 17:02:13 +05:30
Rohit Waghchaure
bc94914338 [Fix] Sales payment summary issue 2018-01-20 17:01:31 +05:30
Rohit Waghchaure
f83f6aae22 [Fix] Wrong projected qty for warehouse group in the process of reorder item making extra material requests 2018-01-20 15:44:38 +05:30
rohitwaghchaure
6a81acfddf Merge pull request #12563 from Zlash65/general-ledger-fix
[Hotfix] General Ledger report not working for group_by_account filter
2018-01-20 12:55:35 +05:30
Rohit Waghchaure
edef642794 Added currency in balance column in general ledger print 2018-01-20 12:54:25 +05:30
Zlash65
93344dff26 group_by_account not displayed fix 2018-01-19 19:06:39 +05:30
Rohit Waghchaure
03adf84a8d Merge branch 'hotfix' 2018-01-19 15:49:29 +05:30
Rohit Waghchaure
0e61b52022 bumped to version 10.0.12 2018-01-19 16:19:28 +06:00
rohitwaghchaure
0efd7934b8 Merge pull request #12530 from frappe/manassolanki-patch-2
Issue in the data import while importing the invoice
2018-01-19 15:35:23 +05:30
Rohit Waghchaure
16cde58821 Merge branch 'hotfix' 2018-01-19 13:29:56 +05:30
Rohit Waghchaure
e1815f0989 bumped to version 10.0.11 2018-01-19 13:59:56 +06:00
rohitwaghchaure
c59d52d073 Merge pull request #12550 from rohitwaghchaure/po_permission_issue
[Fix] Error in PO. No Permission for Buying Settings
2018-01-19 13:00:36 +05:30
rohitwaghchaure
7b605a628e Merge pull request #12543 from rohitwaghchaure/precision_issue_bom
[Fix] Precision issue while making material requests from production planning tool
2018-01-19 13:00:16 +05:30
Rohit Waghchaure
2f3ad64bd6 [Fix] Precision issue while making material requests from production planning tool 2018-01-19 12:47:55 +05:30
Rohit Waghchaure
86cbde9057 [Fix] Error in PO. No Permission for Buying Settings 2018-01-19 12:45:53 +05:30
rohitwaghchaure
65a669c81e Merge pull request #12534 from rohitwaghchaure/patch_fix_v7
[Fix] Timesheet patch
2018-01-19 11:37:18 +05:30
rohitwaghchaure
39e0d1b7d6 Merge pull request #12539 from rohitwaghchaure/minor_sales_payment_summary_issue
[Fix] Sales payment summary issue
2018-01-19 11:34:48 +05:30
Rohit Waghchaure
de420322b5 [Fix] Sales payment summary issue 2018-01-18 17:20:21 +05:30
rohitwaghchaure
c8e016522d Merge pull request #12533 from rohitwaghchaure/pos_css_issue
[Fix] POS css
2018-01-18 16:12:00 +05:30
Rohit Waghchaure
5c4f52ccf1 [Fix] POS css 2018-01-18 16:10:19 +05:30
Rohit Waghchaure
95adb60a8f Fix patch 2018-01-18 15:52:52 +05:30
Manas Solanki
c6d5611408 Issue in the data import while importing the invoice 2018-01-18 11:20:24 +05:30
rohitwaghchaure
bd47abdc9a [Enhance] Running Balance in GL Report (#12491)
* Running Balance in GL Report

* Supplier invoice no in GL Report/Print Format
2018-01-18 09:32:43 +05:30
Faris Ansari
00e547d319 Encode letterhead filename (#12525) 2018-01-18 09:28:13 +05:30
Nabin Hait
f1b098e03c payment terms filter in AR Summary report (#12529) 2018-01-18 09:23:32 +05:30
Nabin Hait
a7bcf6791e Merge branch 'hotfix' 2018-01-17 18:51:20 +05:30
Nabin Hait
f76fb50685 bumped to version 10.0.10 2018-01-17 19:21:20 +06:00
rohitwaghchaure
da941af687 Set due date in purchase invoice based on suppler invoice date (#12395) 2018-01-17 16:23:04 +05:30
Nabin Hait
91fd29a963 Remove enqueuing update_total_sales method, sometimes it does not include current invoice (#12522) 2018-01-17 16:14:31 +05:30
Umair Sayed
230805b016 Update total.html (#12511) 2018-01-17 14:41:38 +05:30
rohitwaghchaure
60febc5465 [Fix] Gross profit validation issue (#12516) 2018-01-17 14:40:59 +05:30
Faris Ansari
4d4ce3e5cf Rename enquiry_type to opportunity_type in MultiSelect dialog (#12517) 2018-01-17 14:40:27 +05:30
Vishal Dhayagude
052b51ab20 [fix] Fetch UOM conversion and stock_uom from BOM into material request (#12513)
* [fix]Fetch UOM conversion and stock_uom from BOM into material Request

* Update material_request.js
2018-01-17 14:39:54 +05:30
Nabin Hait
2bfa1803e9 GL Entry on asset sale (#12514)
* GL Entry on asset sale

* Asset sale test case fixed
2018-01-17 14:39:05 +05:30
Nabin Hait
b44ef0b249 Delete employee records on deletion of company 2018-01-16 19:21:02 +05:30
Saurabh
dfb1646a16 Merge branch 'hotfix' 2018-01-15 18:36:34 +05:30
Saurabh
d40bfeb7d3 bumped to version 10.0.9 2018-01-15 19:06:34 +06:00
Saurabh
af7df6ba50 Merge pull request #12495 from netchampfaris/hotfix-add-ac-2
[fix] is_root check
2018-01-15 18:35:54 +05:30
Faris Ansari
f18cd2eaf7 [fix] is_root check 2018-01-15 18:30:01 +05:30
Nabin Hait
a2426fcc9e Get default tax template only if tax template not selected or template is for other company (#12492) 2018-01-15 17:45:46 +05:30
Faris Ansari
184491bbbe [hotfix] Validate posting_time (#12484) 2018-01-15 14:18:53 +05:30
Vishal Dhayagude
eec0f7fd6b [non_profit][fix] Chapter listing and join and leave chapter issue (#12463)
* [fix] Chapter listing and Join and leave chapter issue

* [minor] Changes in chapter html, chapter title to chapter name
2018-01-15 14:10:23 +05:30
Vishal Dhayagude
e04aedadcd [fix] Add to cart issue fixed (#12474) 2018-01-15 14:01:05 +05:30
Vishal Dhayagude
e88f928f0f [fix] Image with name listing (#12479) 2018-01-15 12:29:39 +05:30
Saurabh
e43a3c269a Merge branch 'hotfix' 2018-01-12 16:54:26 +05:30
Saurabh
59edc6028d bumped to version 10.0.8 2018-01-12 17:24:26 +06:00
Saurabh
93d3020e4b Merge pull request #12464 from Zlash65/fix-company-bom-deletion
[Fix] Delete BOM only when found
2018-01-12 16:47:54 +05:30
Manas Solanki
b19fd57043 [fix] set required quantity if item in bom found (#12460) 2018-01-12 16:28:30 +05:30
rohitwaghchaure
7b78f6bee6 Added rounded total in the POS and fix rounded issue in js side (#12457) 2018-01-12 16:28:16 +05:30
rohitwaghchaure
9fbed5617f [Fix] Wrong batch showing in the popup (#12421) 2018-01-12 16:22:33 +05:30
Manas Solanki
bba5fd7a38 Assessment module addition (#12417)
* add academic session details in the Assessmet Plan

* add the academic session and few details in the assessment result

* fix codacy
2018-01-12 16:21:09 +05:30
Zlash65
c9172e0079 delete boms only when found 2018-01-12 15:59:13 +05:30
Manas Solanki
6c3082591c change the resolution field to the text editor (#12449) 2018-01-12 12:00:13 +05:30
rohitwaghchaure
3955fa5102 [Fix] Email addres unique key issue (#12450) 2018-01-11 18:21:02 +05:30
rohitwaghchaure
02302ff009 [Fix] Incoming rate for gross profit report (#12422) 2018-01-11 12:58:46 +05:30
rohitwaghchaure
5b45bcf5f3 [Fix] Report Available Stock for Packing Items Menu not working (#12400) 2018-01-11 12:39:09 +05:30
rohitwaghchaure
20dead5d91 [minor] UI change (#12440)
* [minor] UI change

* Update company.js
2018-01-11 12:31:14 +05:30
rohitwaghchaure
752d21e658 Code cleanup for item price stock report and fix report was not exporting properly in excel (#12427) 2018-01-11 12:28:48 +05:30
tundebabzy
3732033d9b Merge pull request #12435 from tundebabzy/packing-slip-msg
Better validation message in Packing Slip
2018-01-11 00:32:26 +01:00
tundebabzy
6f75885d86 better validation message 2018-01-10 23:14:13 +01:00
Nabin Hait
527e6c02b3 Delete BOMs on deletion of company 2018-01-09 16:29:13 +05:30
Nabin Hait
6b89644ca7 Payment terms filter in AR report 2018-01-09 15:39:35 +05:30
74 changed files with 1167 additions and 439 deletions

View File

@@ -5,7 +5,7 @@ import frappe
from erpnext.hooks import regional_overrides
from frappe.utils import getdate
__version__ = '10.0.7'
__version__ = '10.0.14'
def get_default_company(user=None):
'''Get default company for user'''

View File

@@ -1,8 +1,8 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"allow_import": 1,
"allow_rename": 1,
"autoname": "field:payment_term_name",
"beta": 0,
"creation": "2017-08-10 15:24:54.876365",
@@ -265,7 +265,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-08-10 16:26:03.581501",
"modified": "2018-01-24 11:13:42.800048",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Term",

View File

@@ -1,8 +1,8 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"allow_import": 1,
"allow_rename": 1,
"autoname": "field:template_name",
"beta": 0,
"creation": "2017-08-10 15:34:28.058054",
@@ -85,7 +85,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-08-10 15:46:33.877884",
"modified": "2018-01-24 11:13:31.158613",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Terms Template",

View File

@@ -25,7 +25,7 @@ class POSProfile(Document):
`tabPOS Profile User` pfu, `tabPOS Profile` pf
where
pf.name = pfu.parent and pfu.user = %s and pf.name != %s and pf.company = %s
and pfu.default=1""", (row.user, self.name, self.company))
and pfu.default=1 and pf.disabled = 0""", (row.user, self.name, self.company))
if row.default and res:
msgprint(_("Already set default in pos profile {0} for user {1}, kindly disabled default")

View File

@@ -18,7 +18,7 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
this.frm.set_df_property("credit_to", "print_hide", 0);
}
} else {
this.frm.set_value("disable_rounded_total", frappe.sys_defaults.disable_rounded_total);
this.frm.set_value("disable_rounded_total", cint(frappe.sys_defaults.disable_rounded_total));
}
// formatter for material request item

View File

@@ -142,7 +142,7 @@ class SalesInvoice(SellingController):
self.update_time_sheet(self.name)
self.update_current_month_sales()
update_company_current_month_sales(self.company)
self.update_project()
def validate_pos_paid_amount(self):
@@ -181,16 +181,9 @@ class SalesInvoice(SellingController):
self.make_gl_entries_on_cancel()
frappe.db.set(self, 'status', 'Cancelled')
self.update_current_month_sales()
update_company_current_month_sales(self.company)
self.update_project()
def update_current_month_sales(self):
if frappe.flags.in_test:
update_company_current_month_sales(self.company)
else:
frappe.enqueue('erpnext.setup.doctype.company.company.update_company_current_month_sales',
company=self.company)
def update_status_updater_args(self):
if cint(self.update_stock):
self.status_updater.extend([{
@@ -675,28 +668,28 @@ class SalesInvoice(SellingController):
# income account gl entries
for item in self.get("items"):
if flt(item.base_net_amount):
account_currency = get_account_currency(item.income_account)
gl_entries.append(
self.get_gl_dict({
"account": item.income_account,
"against": self.customer,
"credit": item.base_net_amount,
"credit_in_account_currency": item.base_net_amount \
if account_currency==self.company_currency else item.net_amount,
"cost_center": item.cost_center
}, account_currency)
)
if item.is_fixed_asset:
asset = frappe.get_doc("Asset", item.asset)
fixed_asset_gl_entries = get_gl_entries_on_asset_disposal(asset, is_sale=True)
fixed_asset_gl_entries = get_gl_entries_on_asset_disposal(asset, item.base_net_amount)
for gle in fixed_asset_gl_entries:
gle["against"] = self.customer
gl_entries.append(self.get_gl_dict(gle))
asset.db_set("disposal_date", self.posting_date)
asset.set_status("Sold" if self.docstatus==1 else None)
else:
account_currency = get_account_currency(item.income_account)
gl_entries.append(
self.get_gl_dict({
"account": item.income_account,
"against": self.customer,
"credit": item.base_net_amount,
"credit_in_account_currency": item.base_net_amount \
if account_currency==self.company_currency else item.net_amount,
"cost_center": item.cost_center
}, account_currency)
)
# expense account gl entries
if cint(self.update_stock) and \

View File

@@ -7,10 +7,10 @@
"docstatus": 0,
"doctype": "Print Format",
"font": "Default",
"html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ doc.company }}<br>\n\t{% if doc.company_address_display %}\n\t\t{% set company_address = doc.company_address_display.replace(\"\\n\", \" \").replace(\"<br>\", \" \") %}\n\t\t{% if \"GSTIN\" not in company_address %}\n\t\t\t{{ company_address }}\n\t\t\t<b>{{ _(\"GSTIN\") }}:</b>{{ doc.company_gstin }}\n\t\t{% else %}\n\t\t\t{{ company_address.replace(\"GSTIN\", \"<br>GSTIN\") }}\n\t\t{% endif %}\n\t{% endif %}\n\t<br>\n\t<b>{{ doc.select_print_heading or _(\"Invoice\") }}</b><br>\n</p>\n<p>\n\t<b>{{ _(\"Receipt No\") }}:</b> {{ doc.name }}<br>\n\t<b>{{ _(\"Date\") }}:</b> {{ doc.get_formatted(\"posting_date\") }}<br>\n\t{% if doc.grand_total > 50000 %}\n\t\t{% set customer_address = doc.address_display.replace(\"\\n\", \" \").replace(\"<br>\", \" \") %}\n\t\t<b>{{ _(\"Customer\") }}:</b><br>\n\t\t{{ doc.customer_name }}<br>\n\t\t{{ customer_address }}\n\t{% endif %}\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"40%\">{{ _(\"Item\") }}</b></th>\n\t\t\t<th width=\"30%\" class=\"text-right\">{{ _(\"Qty\") }}</th>\n\t\t\t<th width=\"30%\" class=\"text-right\">{{ _(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{%- for item in doc.items -%}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t<br>{{ item.item_name }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.gst_hsn_code -%}\n\t\t\t\t\t<br><b>{{ _(\"HSN/SAC\") }}:</b> {{ item.gst_hsn_code }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.serial_no -%}\n\t\t\t\t\t<br><b>{{ _(\"Serial No\") }}:</b> {{ item.serial_no }}\n\t\t\t\t{%- endif -%}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ item.qty }}<br>@ {{ item.rate }}</td>\n\t\t\t<td class=\"text-right\">{{ item.get_formatted(\"amount\") }}</td>\n\t\t</tr>\n\t\t{%- endfor -%}\n\t</tbody>\n</table>\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t{% if doc.flags.show_inclusive_tax_in_print %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% else %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% endif %}\n\t\t</tr>\n\t\t{%- for row in doc.taxes -%}\n\t\t {%- if not row.included_in_print_rate or doc.flags.show_inclusive_tax_in_print -%}\n\t\t\t<tr>\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ row.description }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t\t</td>\n\t\t\t<tr>\n\t\t {%- endif -%}\n\t\t{%- endfor -%}\n\t\t{%- if doc.discount_amount -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t</tbody>\n</table>\n<p><b>Tax Breakup:</b></p>\n<div style=\"font-size: 8px\">\n\t{{ doc.other_charges_calculation }}\n</div>\n<p>{{ doc.terms or \"\" }}</p>\n<p class=\"text-center\">{{ _(\"Thank you, please visit again.\") }}</p>",
"html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ doc.company }}<br>\n\t{% if doc.company_address_display %}\n\t\t{% set company_address = doc.company_address_display.replace(\"\\n\", \" \").replace(\"<br>\", \" \") %}\n\t\t{% if \"GSTIN\" not in company_address %}\n\t\t\t{{ company_address }}\n\t\t\t<b>{{ _(\"GSTIN\") }}:</b>{{ doc.company_gstin }}\n\t\t{% else %}\n\t\t\t{{ company_address.replace(\"GSTIN\", \"<br>GSTIN\") }}\n\t\t{% endif %}\n\t{% endif %}\n\t<br>\n\t<b>{{ doc.select_print_heading or _(\"Invoice\") }}</b><br>\n</p>\n<p>\n\t<b>{{ _(\"Receipt No\") }}:</b> {{ doc.name }}<br>\n\t<b>{{ _(\"Date\") }}:</b> {{ doc.get_formatted(\"posting_date\") }}<br>\n\t{% if doc.grand_total > 50000 %}\n\t\t{% set customer_address = doc.address_display.replace(\"\\n\", \" \").replace(\"<br>\", \" \") %}\n\t\t<b>{{ _(\"Customer\") }}:</b><br>\n\t\t{{ doc.customer_name }}<br>\n\t\t{{ customer_address }}\n\t{% endif %}\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"40%\">{{ _(\"Item\") }}</b></th>\n\t\t\t<th width=\"30%\" class=\"text-right\">{{ _(\"Qty\") }}</th>\n\t\t\t<th width=\"30%\" class=\"text-right\">{{ _(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{%- for item in doc.items -%}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t<br>{{ item.item_name }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.gst_hsn_code -%}\n\t\t\t\t\t<br><b>{{ _(\"HSN/SAC\") }}:</b> {{ item.gst_hsn_code }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.serial_no -%}\n\t\t\t\t\t<br><b>{{ _(\"Serial No\") }}:</b> {{ item.serial_no }}\n\t\t\t\t{%- endif -%}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ item.qty }}<br>@ {{ item.rate }}</td>\n\t\t\t<td class=\"text-right\">{{ item.get_formatted(\"amount\") }}</td>\n\t\t</tr>\n\t\t{%- endfor -%}\n\t</tbody>\n</table>\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t{% if doc.flags.show_inclusive_tax_in_print %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% else %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% endif %}\n\t\t</tr>\n\t\t{%- for row in doc.taxes -%}\n\t\t {%- if not row.included_in_print_rate or doc.flags.show_inclusive_tax_in_print -%}\n\t\t\t<tr>\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ row.description }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t\t</td>\n\t\t\t<tr>\n\t\t {%- endif -%}\n\t\t{%- endfor -%}\n\t\t{%- if doc.discount_amount -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- if doc.rounded_total -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Rounded Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"rounded_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t</tbody>\n</table>\n<p><b>Tax Breakup:</b></p>\n<div style=\"font-size: 8px\">\n\t{{ doc.other_charges_calculation }}\n</div>\n<p>{{ doc.terms or \"\" }}</p>\n<p class=\"text-center\">{{ _(\"Thank you, please visit again.\") }}</p>",
"idx": 0,
"line_breaks": 0,
"modified": "2018-01-05 17:25:59.181985",
"modified": "2018-01-12 11:19:17.432600",
"modified_by": "Administrator",
"module": "Accounts",
"name": "GST POS Invoice",

View File

@@ -2,14 +2,14 @@
"align_labels_right": 0,
"creation": "2011-12-21 11:08:55",
"custom_format": 1,
"disabled": 0,
"disabled": 1,
"doc_type": "Sales Invoice",
"docstatus": 0,
"doctype": "Print Format",
"html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ doc.company }}<br>\n\t{{ doc.select_print_heading or _(\"Invoice\") }}<br>\n</p>\n<p>\n\t<b>{{ _(\"Receipt No\") }}:</b> {{ doc.name }}<br>\n\t<b>{{ _(\"Date\") }}:</b> {{ doc.get_formatted(\"posting_date\") }}<br>\n\t<b>{{ _(\"Customer\") }}:</b> {{ doc.customer_name }}\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"50%\">{{ _(\"Item\") }}</b></th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ _(\"Qty\") }}</th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ _(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{%- for item in doc.items -%}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t<br>{{ item.item_name }}{%- endif -%}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ item.qty }}<br>@ {{ item.get_formatted(\"rate\") }}</td>\n\t\t\t<td class=\"text-right\">{{ item.get_formatted(\"amount\") }}</td>\n\t\t</tr>\n\t\t{%- endfor -%}\n\t</tbody>\n</table>\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t{% if doc.flags.show_inclusive_tax_in_print %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% else %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% endif %}\n\t\t</tr>\n\t\t{%- for row in doc.taxes -%}\n\t\t {%- if not row.included_in_print_rate or doc.flags.show_inclusive_tax_in_print -%}\n\t\t\t<tr>\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ row.description }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t\t</td>\n\t\t\t<tr>\n\t\t {%- endif -%}\n\t\t{%- endfor -%}\n\n\t\t{%- if doc.discount_amount -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t</tbody>\n</table>\n<hr>\n<p>{{ doc.terms or \"\" }}</p>\n<p class=\"text-center\">{{ _(\"Thank you, please visit again.\") }}</p>",
"html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ doc.company }}<br>\n\t{{ doc.select_print_heading or _(\"Invoice\") }}<br>\n</p>\n<p>\n\t<b>{{ _(\"Receipt No\") }}:</b> {{ doc.name }}<br>\n\t<b>{{ _(\"Date\") }}:</b> {{ doc.get_formatted(\"posting_date\") }}<br>\n\t<b>{{ _(\"Customer\") }}:</b> {{ doc.customer_name }}\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"50%\">{{ _(\"Item\") }}</b></th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ _(\"Qty\") }}</th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ _(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{%- for item in doc.items -%}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t<br>{{ item.item_name }}{%- endif -%}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ item.qty }}<br>@ {{ item.get_formatted(\"rate\") }}</td>\n\t\t\t<td class=\"text-right\">{{ item.get_formatted(\"amount\") }}</td>\n\t\t</tr>\n\t\t{%- endfor -%}\n\t</tbody>\n</table>\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t{% if doc.flags.show_inclusive_tax_in_print %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% else %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% endif %}\n\t\t</tr>\n\t\t{%- for row in doc.taxes -%}\n\t\t {%- if not row.included_in_print_rate or doc.flags.show_inclusive_tax_in_print -%}\n\t\t\t<tr>\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ row.description }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t\t</td>\n\t\t\t<tr>\n\t\t {%- endif -%}\n\t\t{%- endfor -%}\n\n\t\t{%- if doc.discount_amount -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- if doc.rounded_total -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Rounded Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"rounded_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t</tbody>\n</table>\n<hr>\n<p>{{ doc.terms or \"\" }}</p>\n<p class=\"text-center\">{{ _(\"Thank you, please visit again.\") }}</p>",
"idx": 1,
"line_breaks": 0,
"modified": "2018-01-05 17:23:40.403289",
"modified": "2018-01-12 11:18:54.229254",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Invoice",

View File

@@ -23,10 +23,10 @@ frappe.query_reports["Accounts Receivable"] = {
"options": "Customer Group"
},
{
"fieldname":"credit_days_based_on",
"label": __("Credit Days Based On"),
"fieldtype": "Select",
"options": "\nFixed Days\nLast Day of the Next Month"
"fieldname":"payment_terms_template",
"label": __("Payment Terms Template"),
"fieldtype": "Link",
"options": "Payment Terms Template"
},
{
"fieldtype": "Break",

View File

@@ -283,9 +283,9 @@ class ReceivablePayableReport(object):
where exists(select name from `tabCustomer Group` where lft >= {0} and rgt <= {1}
and name=tabCustomer.customer_group))""".format(lft, rgt))
if self.filters.get("credit_days_based_on"):
conditions.append("party in (select name from tabCustomer where credit_days_based_on=%s)")
values.append(self.filters.get("credit_days_based_on"))
if self.filters.get("payment_terms_template"):
conditions.append("party in (select name from tabCustomer where payment_terms=%s)")
values.append(self.filters.get("payment_terms_template"))
return " and ".join(conditions), values

View File

@@ -23,10 +23,10 @@ frappe.query_reports["Accounts Receivable Summary"] = {
"options": "Customer Group"
},
{
"fieldname":"credit_days_based_on",
"label": __("Credit Days Based On"),
"fieldtype": "Select",
"options": "\nFixed Days\nLast Day of the Next Month"
"fieldname":"payment_terms_template",
"label": __("Payment Terms Template"),
"fieldtype": "Link",
"options": "Payment Terms Template"
},
{
"fieldtype": "Break",

View File

@@ -17,38 +17,70 @@
<table class="table table-bordered">
<thead>
<tr>
<th style="width: 15%">{%= __("Date") %}</th>
<th style="width: 12%">{%= __("Date") %}</th>
<th style="width: 15%">{%= __("Ref") %}</th>
<th style="width: 40%">{%= __("Party") %}</th>
<th style="width: 25%">{%= __("Party") %}</th>
<th style="width: 15%">{%= __("Debit") %}</th>
<th style="width: 15%">{%= __("Credit") %}</th>
<th style="width: 18%">{%= __("Balance") %}</th>
</tr>
</thead>
<tbody>
{% for(var i=0, l=data.length; i<l; i++) { %}
<tr>
{% if(data[i][__("Posting Date")]) { %}
<td>{%= dateutil.str_to_user(data[i][__("Posting Date")]) %}</td>
<td>{%= data[i][__("Voucher Type")] %}
<br>{%= data[i][__("Voucher No")] %}</td>
{% if(data[i].posting_date) { %}
<td>{%= dateutil.str_to_user(data[i].posting_date) %}</td>
<td>{%= data[i].voucher_type %}
<br>{%= data[i].voucher_no %}</td>
<td>
{% if(!(filters.party || filters.account)) { %}
{%= data[i][__("Party")] || data[i][__("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>
{{ __("Against") }}: {%= data[i].against %}
<br>{%= __("Remarks") %}: {%= data[i].remarks %}
{% if(data[i].bill_no) { %}
<br>{%= __("Supplier Invoice No") %}: {%= data[i].bill_no %}
{% } %}
</td>
{% if(filters.print_in_account_currency) { %}
<td style="text-align: right">
{%= format_currency(data[i].debit_in_account_currency, data[i].account_currency) %}
</td>
<td style="text-align: right">
{%= format_currency(data[i].credit_in_account_currency, data[i].account_currency) %}
</td>
{% } else { %}
<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>{%= frappe.format(data[i][__("Account")], {fieldtype: "Link"}) || "&nbsp;" %}</b></td>
<td style="text-align: right">
{%= data[i][__("Account")] && format_currency(data[i][__("Debit")]) %}</td>
<td style="text-align: right">
{%= data[i][__("Account")] && format_currency(data[i][__("Credit")]) %}</td>
<td><b>{%= frappe.format(data[i].account, {fieldtype: "Link"}) || "&nbsp;" %}</b></td>
{% if(filters.print_in_account_currency) { %}
<td style="text-align: right">
{%= data[i].account && format_currency(data[i].debit_in_account_currency, data[i].account_currency) %}</td>
<td style="text-align: right">
{%= data[i].account && format_currency(data[i].credit_in_account_currency, data[i].account_currency) %}</td>
{% } else { %}
<td style="text-align: right">
{%= data[i].account && format_currency(data[i].debit) %}
</td>
<td style="text-align: right">
{%= data[i].account && format_currency(data[i].credit) %}
</td>
{% } %}
{% } %}
{% if(filters.print_in_account_currency) { %}
<td style="text-align: right">{%= get_currency_symbol(data[i].account_currency)%}
{%= data[i].balance_in_account_currency %}</td>
{% } else { %}
<td style="text-align: right">{%= get_currency_symbol()%}
{%= data[i].balance %}</td>
{% } %}
</tr>
{% } %}

View File

@@ -105,6 +105,11 @@ frappe.query_reports["General Ledger"] = {
"fieldname":"group_by_account",
"label": __("Group by Account"),
"fieldtype": "Check",
},
{
"fieldname":"print_in_account_currency",
"label": __("Print in Account Currency"),
"fieldtype": "Check",
}
]
}

View File

@@ -3,12 +3,17 @@
from __future__ import unicode_literals
import frappe
from frappe.utils import getdate, cstr, flt
from frappe.utils import getdate, cstr, flt, fmt_money
from frappe import _, _dict
from erpnext.accounts.utils import get_account_currency
def execute(filters=None):
account_details = {}
if filters and filters.get('print_in_account_currency') and \
not filters.get('account'):
frappe.throw(_("Select an account to print in account currency"))
for acc in frappe.db.sql("""select name, is_group from tabAccount""", as_dict=1):
account_details.setdefault(acc.name, acc)
@@ -76,28 +81,6 @@ def set_account_currency(filters):
return filters
def get_columns(filters):
columns = [
_("Posting Date") + ":Date:90", _("Account") + ":Link/Account:200",
_("Debit") + ":Float:100", _("Credit") + ":Float:100"
]
if filters.get("show_in_account_currency"):
columns += [
_("Debit") + " (" + filters.account_currency + ")" + ":Float:100",
_("Credit") + " (" + filters.account_currency + ")" + ":Float:100"
]
columns += [
_("Voucher Type") + "::120", _("Voucher No") + ":Dynamic Link/"+_("Voucher Type")+":160",
_("Against Account") + "::120", _("Party Type") + "::80", _("Party") + "::150",
_("Project") + ":Link/Project:100", _("Cost Center") + ":Link/Cost Center:100",
_("Against Voucher Type") + "::120", _("Against Voucher") + ":Dynamic Link/"+_("Against Voucher Type")+":160",
_("Remarks") + "::400"
]
return columns
def get_result(filters, account_details):
gl_entries = get_gl_entries(filters)
@@ -193,24 +176,6 @@ def get_data_with_opening_closing(filters, account_details, gl_entries):
# closing
data.append(totals.closing)
#total closing
total_closing = totals.total_closing
total_debit = totals.closing.get('debit', 0)
total_credit = totals.closing.get('credit', 0)
debit_in_account_currency = totals.closing.get('debit_in_account_currency', 0)
credit_in_account_currency = totals.closing.get('credit_in_account_currency', 0)
total_amount = total_debit - total_credit
if total_amount > 0:
total_closing['debit'] = total_amount
total_closing['debit_in_account_currency'] = debit_in_account_currency - credit_in_account_currency
else:
total_closing['credit'] = abs(total_amount)
total_closing['credit_in_account_currency'] = abs(debit_in_account_currency - credit_in_account_currency)
data.append(totals.total_closing)
return data
def get_totals_dict():
@@ -225,8 +190,7 @@ def get_totals_dict():
return _dict(
opening = _get_debit_credit_dict(_('Opening')),
total = _get_debit_credit_dict(_('Total')),
closing = _get_debit_credit_dict(_('Closing (Opening + Total)')),
total_closing = _get_debit_credit_dict(_('Closing Balance (Dr - Cr)'))
closing = _get_debit_credit_dict(_('Closing (Opening + Total)'))
)
def initialize_gle_map(gl_entries):
@@ -270,17 +234,164 @@ def get_accountwise_gle(filters, gl_entries, gle_map):
return totals, entries
def get_result_as_list(data, filters):
result = []
balance, balance_in_account_currency = 0, 0
inv_details = get_supplier_invoice_details()
for d in data:
row = [d.get("posting_date"), d.get("account"), d.get("debit"), d.get("credit")]
if not d.get('posting_date'):
balance, balance_in_account_currency = 0, 0
balance, label = get_balance(d, balance, 'debit', 'credit')
d['balance'] = '{0} {1}'.format(fmt_money(abs(balance)), label)
if filters.get("show_in_account_currency"):
row += [d.get("debit_in_account_currency"), d.get("credit_in_account_currency")]
balance_in_account_currency, label = get_balance(d, balance_in_account_currency,
'debit_in_account_currency', 'credit_in_account_currency')
d['balance_in_account_currency'] = '{0} {1}'.format(fmt_money(abs(balance_in_account_currency)), label)
else:
d['debit_in_account_currency'] = d.get('debit', 0)
d['credit_in_account_currency'] = d.get('credit', 0)
d['balance_in_account_currency'] = d.get('balance')
row += [d.get("voucher_type"), d.get("voucher_no"), d.get("against"),
d.get("party_type"), d.get("party"), d.get("project"), d.get("cost_center"), d.get("against_voucher_type"), d.get("against_voucher"), d.get("remarks")
]
d['account_currency'] = filters.account_currency
d['bill_no'] = inv_details.get(d.get('against_voucher'), '')
result.append(row)
return data
return result
def get_supplier_invoice_details():
inv_details = {}
for d in frappe.db.sql(""" select name, bill_no from `tabPurchase Invoice`
where docstatus = 1 and bill_no is not null and bill_no != '' """, as_dict=1):
inv_details[d.name] = d.bill_no
return inv_details
def get_balance(row, balance, debit_field, credit_field):
balance += (row.get(debit_field, 0) - row.get(credit_field, 0))
label = 'DR' if balance > 0 else 'CR'
return balance, label
def get_columns(filters):
columns = [
{
"label": _("Posting Date"),
"fieldname": "posting_date",
"fieldtype": "Date",
"width": 90
},
{
"label": _("Account"),
"fieldname": "account",
"fieldtype": "Link",
"options": "Account",
"width": 180
},
{
"label": _("Debit"),
"fieldname": "debit",
"fieldtype": "Float",
"width": 100
},
{
"label": _("Credit"),
"fieldname": "credit",
"fieldtype": "Float",
"width": 100
},
{
"label": _("Balance"),
"fieldname": "balance",
"fieldtype": "Data",
"width": 100
}
]
if filters.get("show_in_account_currency"):
columns.extend([
{
"label": _("Debit") + " (" + filters.account_currency + ")",
"fieldname": "debit_in_account_currency",
"fieldtype": "Float",
"width": 100
},
{
"label": _("Credit") + " (" + filters.account_currency + ")",
"fieldname": "credit_in_account_currency",
"fieldtype": "Float",
"width": 100
},
{
"label": _("Balance") + " (" + filters.account_currency + ")",
"fieldname": "balance_in_account_currency",
"fieldtype": "Data",
"width": 100
}
])
columns.extend([
{
"label": _("Voucher Type"),
"fieldname": "voucher_type",
"width": 120
},
{
"label": _("Voucher No"),
"fieldname": "voucher_no",
"fieldtype": "Dynamic Link",
"options": "voucher_type",
"width": 180
},
{
"label": _("Against Account"),
"fieldname": "against",
"width": 120
},
{
"label": _("Party Type"),
"fieldname": "party_type",
"width": 100
},
{
"label": _("Party"),
"fieldname": "party",
"width": 100
},
{
"label": _("Project"),
"options": "Project",
"fieldname": "project",
"width": 100
},
{
"label": _("Cost Center"),
"options": "Cost Center",
"fieldname": "cost_center",
"width": 100
},
{
"label": _("Against Voucher Type"),
"fieldname": "against_voucher_type",
"width": 100
},
{
"label": _("Against Voucher"),
"fieldname": "against_voucher",
"fieldtype": "Dynamic Link",
"options": "against_voucher_type",
"width": 100
},
{
"label": _("Supplier Invoice No"),
"fieldname": "bill_no",
"fieldtype": "Data",
"width": 100
},
{
"label": _("Remarks"),
"fieldname": "remarks",
"width": 400
}
])
return columns

View File

@@ -6,7 +6,6 @@ import frappe
from frappe import _, scrub
from erpnext.stock.utils import get_incoming_rate
from erpnext.controllers.queries import get_match_cond
from erpnext.stock.stock_ledger import get_valuation_rate
from frappe.utils import flt
@@ -248,6 +247,7 @@ class GrossProfitGenerator(object):
return 0.0
def get_average_buying_rate(self, row, item_code):
args = row
if not item_code in self.average_buying_rate:
if item_code in self.non_stock_items:
self.average_buying_rate[item_code] = flt(frappe.db.sql("""
@@ -255,12 +255,14 @@ class GrossProfitGenerator(object):
from `tabPurchase Invoice Item`
where item_code = %s and docstatus=1""", item_code)[0][0])
else:
average_buying_rate = get_incoming_rate(row)
if not average_buying_rate:
average_buying_rate = get_valuation_rate(item_code, row.warehouse,
row.parenttype, row.parent, allow_zero_rate=True,
currency=self.filters.currency, company=self.filters.company)
args.update({
'voucher_type': row.parenttype,
'voucher_no': row.parent,
'allow_zero_valuation': True,
'company': self.filters.company
})
average_buying_rate = get_incoming_rate(args)
self.average_buying_rate[item_code] = flt(average_buying_rate)
return self.average_buying_rate[item_code]

View File

@@ -36,8 +36,8 @@ def get_sales_payment_data(filters, columns):
return data
def get_conditions(filters):
conditions = ""
if filters.get("from_date"): conditions += "a.posting_date >= %(from_date)s"
conditions = "1=1"
if filters.get("from_date"): conditions += " and a.posting_date >= %(from_date)s"
if filters.get("to_date"): conditions += " and a.posting_date <= %(to_date)s"
if filters.get("company"): conditions += " and a.company=%(company)s"
if filters.get("customer"): conditions += " and a.customer = %(customer)s"

View File

@@ -252,7 +252,7 @@ def add_ac(args=None):
if not ac.parent_account:
ac.parent_account = args.get("parent")
if ac.is_root:
if getattr(ac, 'is_root', None):
ac.parent_account=''
ac.old_parent = ""

View File

@@ -51,9 +51,6 @@ class Asset(Document):
if not self.get(field):
self.set(field, value)
self.value_after_depreciation = (flt(self.gross_purchase_amount) -
flt(self.opening_accumulated_depreciation))
def validate_asset_values(self):
if flt(self.expected_value_after_useful_life) >= flt(self.gross_purchase_amount):
frappe.throw(_("Expected Value After Useful Life must be less than Gross Purchase Amount"))
@@ -61,7 +58,10 @@ class Asset(Document):
if not flt(self.gross_purchase_amount):
frappe.throw(_("Gross Purchase Amount is mandatory"), frappe.MandatoryError)
if not self.is_existing_asset and self.calculate_depreciation:
if not self.calculate_depreciation:
return
if not self.is_existing_asset:
self.opening_accumulated_depreciation = 0
self.number_of_depreciations_booked = 0
if not self.next_depreciation_date:
@@ -81,6 +81,9 @@ class Asset(Document):
if cint(self.number_of_depreciations_booked) > cint(self.total_number_of_depreciations):
frappe.throw(_("Number of Depreciations Booked cannot be greater than Total Number of Depreciations"))
self.value_after_depreciation = (flt(self.gross_purchase_amount) -
flt(self.opening_accumulated_depreciation))
if self.next_depreciation_date and getdate(self.next_depreciation_date) < getdate(nowdate()):
frappe.msgprint(_("Next Depreciation Date is entered as past date"), title=_('Warning'), indicator='red')
@@ -106,12 +109,13 @@ class Asset(Document):
n * cint(self.frequency_of_depreciation))
depreciation_amount = self.get_depreciation_amount(value_after_depreciation)
value_after_depreciation -= flt(depreciation_amount)
if depreciation_amount:
value_after_depreciation -= flt(depreciation_amount)
self.append("schedules", {
"schedule_date": schedule_date,
"depreciation_amount": depreciation_amount
})
self.append("schedules", {
"schedule_date": schedule_date,
"depreciation_amount": depreciation_amount
})
def set_accumulated_depreciation(self):
accumulated_depreciation = flt(self.opening_accumulated_depreciation)

View File

@@ -151,13 +151,11 @@ def restore_asset(asset_name):
asset.set_status()
@frappe.whitelist()
def get_gl_entries_on_asset_disposal(asset, is_sale=False):
def get_gl_entries_on_asset_disposal(asset, selling_amount=0):
fixed_asset_account, accumulated_depr_account, depr_expense_account = get_depreciation_accounts(asset)
accumulated_depr_amount = flt(asset.gross_purchase_amount) - flt(asset.value_after_depreciation)
disposal_account, depreciation_cost_center = get_disposal_account_and_cost_center(asset.company)
expense_account, cost_center = get_disposal_account_and_cost_center(asset.company)
if is_sale:
expense_account = depr_expense_account
accumulated_depr_amount = flt(asset.gross_purchase_amount) - flt(asset.value_after_depreciation)
gl_entries = [
{
@@ -172,12 +170,14 @@ def get_gl_entries_on_asset_disposal(asset, is_sale=False):
}
]
if flt(asset.value_after_depreciation):
profit_amount = flt(selling_amount) - flt(asset.value_after_depreciation)
if profit_amount:
debit_or_credit = "debit" if profit_amount < 0 else "credit"
gl_entries.append({
"account": expense_account,
"cost_center": cost_center,
"debit": flt(asset.value_after_depreciation),
"debit_in_account_currency": flt(asset.value_after_depreciation)
"account": disposal_account,
"cost_center": depreciation_cost_center,
debit_or_credit: abs(profit_amount),
debit_or_credit + "_in_account_currency": abs(profit_amount)
})
return gl_entries

View File

@@ -234,9 +234,8 @@ class TestAsset(unittest.TestCase):
expected_gle = (
("_Test Accumulated Depreciations - _TC", 30000.0, 0.0),
("_Test Depreciations - _TC", 70000.0, 0.0),
("_Test Fixed Asset - _TC", 0.0, 100000.0),
("_Test Gain/Loss on Asset Disposal - _TC", 0.0, 25000.0),
("_Test Gain/Loss on Asset Disposal - _TC", 45000.0, 0.0),
("Debtors - _TC", 25000.0, 0.0)
)

View File

@@ -21,10 +21,10 @@ frappe.ui.form.on("Purchase Order", {
return erpnext.queries.warehouse(frm.doc);
});
frappe.db.get_value('Buying Settings', {name: 'Buying Settings'}, 'disable_fetch_last_purchase_rate', (r) => {
value = r && cint(r.disable_fetch_last_purchase_rate);
frm.toggle_display('get_last_purchase_rate', !value);
});
if (frm.doc.__onload) {
frm.toggle_display('get_last_purchase_rate',
frm.doc.__onload.disable_fetch_last_purchase_rate);
}
frm.set_indicator_formatter('item_code',
function(doc) { return (doc.qty<=doc.received_qty) ? "green" : "orange" })

View File

@@ -34,6 +34,12 @@ class PurchaseOrder(BuyingController):
'overflow_type': 'order'
}]
def onload(self):
super(PurchaseOrder, self).onload()
self.set_onload('disable_fetch_last_purchase_rate',
cint(frappe.db.get_single_value("Buying Settings", "disable_fetch_last_purchase_rate")))
def validate(self):
super(PurchaseOrder, self).validate()

View File

@@ -54,6 +54,7 @@ class AccountsController(TransactionBase):
if self.meta.get_field("taxes_and_charges"):
self.validate_enabled_taxes_and_charges()
self.validate_tax_account_company()
self.validate_party()
self.validate_currency()
@@ -255,6 +256,14 @@ class AccountsController(TransactionBase):
if frappe.db.get_value(taxes_and_charges_doctype, self.taxes_and_charges, "disabled"):
frappe.throw(_("{0} '{1}' is disabled").format(taxes_and_charges_doctype, self.taxes_and_charges))
def validate_tax_account_company(self):
for d in self.get("taxes"):
if d.account_head:
tax_account_company = frappe.db.get_value("Account", d.account_head, "company")
if tax_account_company != self.company:
frappe.throw(_("Row #{0}: Account {1} does not belong to company {2}")
.format(d.idx, d.account_head, self.company))
def get_gl_dict(self, args, account_currency=None):
"""this method populates the common properties of a gl entry record"""
@@ -475,7 +484,7 @@ class AccountsController(TransactionBase):
max_allowed_amt = flt(ref_amt * (100 + tolerance) / 100)
if total_billed_amt - max_allowed_amt > 0.01:
frappe.throw(_("Cannot overbill for Item {0} in row {1} more than {2}. To allow over-billing, please set in Buying Settings").format(item.item_code, item.idx, max_allowed_amt))
frappe.throw(_("Cannot overbill for Item {0} in row {1} more than {2}. To allow over-billing, please set in Stock Settings").format(item.item_code, item.idx, max_allowed_amt))
def get_company_default(self, fieldname):
from erpnext.accounts.utils import get_company_default
@@ -657,7 +666,7 @@ class AccountsController(TransactionBase):
self.remove(item)
def set_payment_schedule(self):
posting_date = self.get("posting_date") or self.get("transaction_date")
posting_date = self.get("bill_date") or self.get("posting_date") or self.get("transaction_date")
date = self.get("due_date")
due_date = date or posting_date
grand_total = self.get("rounded_total") or self.grand_total
@@ -722,11 +731,15 @@ def get_tax_rate(account_head):
return frappe.db.get_value("Account", account_head, ["tax_rate", "account_name"], as_dict=True)
@frappe.whitelist()
def get_default_taxes_and_charges(master_doctype, company=None):
def get_default_taxes_and_charges(master_doctype, tax_template=None, company=None):
if not company: return {}
default_tax = frappe.db.get_value(master_doctype,
{"is_default": 1, "company": company})
if tax_template and company:
tax_template_company = frappe.db.get_value(master_doctype, tax_template, "company")
if tax_template_company == company:
return
default_tax = frappe.db.get_value(master_doctype, {"is_default": 1, "company": company})
return {
'taxes_and_charges': default_tax,

View File

@@ -152,7 +152,7 @@ def tax_account_query(doctype, txt, searchfield, start, page_len, filters):
def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=False):
conditions = []
return frappe.db.sql("""select tabItem.name, tabItem.item_group, tabItem.image,
return frappe.db.sql("""select tabItem.name, tabItem.item_group,
if(length(tabItem.item_name) > 40,
concat(substr(tabItem.item_name, 1, 40), "..."), item_name) as item_name,
if(length(tabItem.description) > 40, \
@@ -414,10 +414,11 @@ def get_doctype_wise_filters(filters):
@frappe.whitelist()
def get_batch_numbers(doctype, txt, searchfield, start, page_len, filters):
query = 'select batch_id from `tabBatch` ' \
'where (`tabBatch`.expiry_date >= CURDATE() or `tabBatch`.expiry_date IS NULL)'
query = """select batch_id from `tabBatch`
where (expiry_date >= CURDATE() or expiry_date IS NULL)
and name like '{txt}'""".format(txt = frappe.db.escape('%{0}%'.format(txt)))
if filters and filters.get('item_code'):
query += 'where item = %(item_code)s' % filters
if filters and filters.get('item'):
query += " and item = '{item}'".format(item = frappe.db.escape(filters.get('item')))
return frappe.db.sql(query)

View File

@@ -232,7 +232,7 @@ def make_quotation(source_name, target_doc=None):
quotation.conversion_rate = exchange_rate
# get default taxes
taxes = get_default_taxes_and_charges("Sales Taxes and Charges Template", quotation.company)
taxes = get_default_taxes_and_charges("Sales Taxes and Charges Template", company=quotation.company)
if taxes.get('taxes'):
quotation.update(taxes)

View File

@@ -1,41 +1,46 @@
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
cur_frm.add_fetch("student_group", "course", "course");
cur_frm.add_fetch("examiner", "instructor_name", "examiner_name");
cur_frm.add_fetch("supervisor", "instructor_name", "supervisor_name");
cur_frm.add_fetch("course", "default_grading_scale", "grading_scale");
frappe.ui.form.on("Assessment Plan", {
onload: function(frm) {
frm.set_query("assessment_group", function(doc, cdt, cdn) {
return{
filters: {
'is_group': 0
}
}
});
},
refresh: function(frm) {
if (frm.doc.docstatus == 1) {
frm.add_custom_button(__("Assessment Result"), function() {
frappe.route_options = {
assessment_plan: frm.doc.name,
student_group: frm.doc.student_group
}
frappe.set_route("Form", "Assessment Result Tool");
});
}
setup: function(frm) {
frm.add_fetch("student_group", "course", "course");
frm.add_fetch("student_group", "program", "program");
frm.add_fetch("student_group", "academic_year", "academic_year");
frm.add_fetch("student_group", "academic_term", "academic_term");
frm.add_fetch("examiner", "instructor_name", "examiner_name");
frm.add_fetch("supervisor", "instructor_name", "supervisor_name");
frm.add_fetch("course", "default_grading_scale", "grading_scale");
},
onload: function(frm) {
frm.set_query("assessment_group", function(doc, cdt, cdn) {
return{
filters: {
'is_group': 0
}
};
});
frm.set_query('grading_scale', function(){
return {
filters: {
docstatus: 1
}
}
};
});
},
},
refresh: function(frm) {
if (frm.doc.docstatus == 1) {
frm.add_custom_button(__("Assessment Result"), function() {
frappe.route_options = {
assessment_plan: frm.doc.name,
student_group: frm.doc.student_group
}
frappe.set_route("Form", "Assessment Result Tool");
});
}
},
course: function(frm) {
if (frm.doc.course && frm.doc.maximum_assessment_score) {

View File

@@ -13,36 +13,6 @@
"editable_grid": 0,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "assessment_name",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 1,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Assessment Name",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -80,19 +50,80 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "course",
"fieldtype": "Link",
"fieldname": "assessment_name",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 1,
"in_list_view": 0,
"in_standard_filter": 1,
"label": "Course",
"in_standard_filter": 0,
"label": "Assessment Name",
"length": 0,
"no_copy": 0,
"options": "Course",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "assessment_group",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 1,
"label": "Assessment Group",
"length": 0,
"no_copy": 0,
"options": "Assessment Group",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "grading_scale",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 1,
"label": "Grading Scale",
"length": 0,
"no_copy": 0,
"options": "Grading Scale",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -140,19 +171,50 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "assessment_group",
"fieldname": "course",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_global_search": 1,
"in_list_view": 0,
"in_standard_filter": 1,
"label": "Assessment Group",
"label": "Course",
"length": 0,
"no_copy": 0,
"options": "Assessment Group",
"options": "Course",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "program",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 1,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Program",
"length": 0,
"no_copy": 0,
"options": "Program",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -171,8 +233,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "maximum_assessment_score",
"fieldtype": "Float",
"fieldname": "academic_year",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -180,9 +242,10 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Maximum Assessment Score",
"label": "Academic Year",
"length": 0,
"no_copy": 0,
"options": "Academic Year",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -190,7 +253,7 @@
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
@@ -201,7 +264,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "grading_scale",
"fieldname": "academic_term",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -209,11 +272,11 @@
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 1,
"label": "Grading Scale",
"in_standard_filter": 0,
"label": "Academic Term",
"length": 0,
"no_copy": 0,
"options": "Grading Scale",
"options": "Academic Term",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -221,7 +284,7 @@
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
@@ -546,6 +609,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Evaluate",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -560,6 +624,36 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "maximum_assessment_score",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Maximum Assessment Score",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -633,7 +727,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2017-11-28 17:23:36.657725",
"modified": "2018-01-08 17:53:39.340356",
"modified_by": "Administrator",
"module": "Education",
"name": "Assessment Plan",

View File

@@ -9,10 +9,22 @@ from frappe import _
class AssessmentPlan(Document):
def validate(self):
self.set_missing_field()
self.validate_overlap()
self.validate_max_score()
self.validate_assessment_criteria()
def set_missing_field(self):
if self.student_group:
academic_term, academic_year, program, course = frappe.get_value("Student Group", self.student_group,
["academic_term", "academic_year", "program", "course"])
self.academic_term = academic_term
self.academic_year = academic_year
if program:
self.program = program
if course and not self.course: #pylint: disable=E0203
self.course = course
def validate_overlap(self):
"""Validates overlap for Student Group, Instructor, Room"""

View File

@@ -1,11 +1,29 @@
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
cur_frm.add_fetch("student", "title", "student_name");
cur_frm.add_fetch("assessment_plan", "grading_scale", "grading_scale");
cur_frm.add_fetch("assessment_plan", "maximum_assessment_score", "maximum_score");
frappe.ui.form.on("Assessment Result", {
setup: function(frm) {
frm.add_fetch("student", "title", "student_name");
frm.add_fetch("assessment_plan", "course", "course");
frm.add_fetch("assessment_plan", "program", "program");
frm.add_fetch("assessment_plan", "academic_year", "academic_year");
frm.add_fetch("assessment_plan", "academic_term", "academic_term");
frm.add_fetch("assessment_plan", "grading_scale", "grading_scale");
frm.add_fetch("assessment_plan", "student_group", "student_group");
frm.add_fetch("assessment_plan", "assessment_group", "assessment_group");
frm.add_fetch("assessment_plan", "maximum_assessment_score", "maximum_score");
},
onload: function(frm) {
frm.set_query('assessment_plan', function(){
return {
filters: {
docstatus: 1
}
};
});
},
assessment_plan: function(frm) {
if (frm.doc.assessment_plan) {
frappe.call({

View File

@@ -13,6 +13,190 @@
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "assessment_plan",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Assessment Plan",
"length": 0,
"no_copy": 0,
"options": "Assessment Plan",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "program",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Program",
"length": 0,
"no_copy": 0,
"options": "Program",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "course",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Course",
"length": 0,
"no_copy": 0,
"options": "Course",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "academic_year",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Academic Year",
"length": 0,
"no_copy": 0,
"options": "Academic Year",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "academic_term",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Academic Term",
"length": 0,
"no_copy": 0,
"options": "Academic Term",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_3",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -80,8 +264,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_3",
"fieldtype": "Column Break",
"fieldname": "student_group",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -89,8 +273,10 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Student Group",
"length": 0,
"no_copy": 0,
"options": "Student Group",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -109,19 +295,19 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "assessment_plan",
"fieldname": "assessment_group",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Assessment Plan",
"label": "Assessment Group",
"length": 0,
"no_copy": 0,
"options": "Assessment Plan",
"options": "Assessment Group",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -129,7 +315,7 @@
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
@@ -180,6 +366,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Result",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -285,6 +472,35 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_11",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -315,35 +531,6 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_11",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -389,6 +576,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Summary",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -474,7 +662,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-11-10 18:58:32.114529",
"modified": "2018-01-09 14:14:30.090317",
"modified_by": "Administrator",
"module": "Education",
"name": "Assessment Result",

View File

@@ -14,15 +14,25 @@ from frappe.utils.csvutils import getlink
class AssessmentResult(Document):
def validate(self):
if self.student and not self.student_name:
self.student_name = frappe.db.get_value("Student", self.student, "title")
self.grading_scale = frappe.db.get_value("Assessment Plan", self.assessment_plan, "grading_scale")
self.set_missing_values()
self.validate_maximum_score()
self.validate_grade()
self.validate_duplicate()
def set_missing_values(self):
if self.student and not self.student_name:
self.student_name = frappe.db.get_value("Student", self.student, "title")
assessment_plan_details = frappe.get_value("Assessment Plan", self.assessment_plan, ["academic_term",
"academic_year", "program", "course", "grading_scale", "assessment_group", "student_group",
"maximum_assessment_score"], as_dict=1)
for field in assessment_plan_details:
if field != "maximum_assessment_score":
setattr(self, field, assessment_plan_details[field])
else:
self.maximum_score = assessment_plan_details[field]
def validate_maximum_score(self):
self.maximum_score = frappe.db.get_value("Assessment Plan", self.assessment_plan, "maximum_assessment_score")
assessment_details = get_assessment_details(self.assessment_plan)
max_scores = {}
for d in assessment_details:

View File

@@ -10,6 +10,7 @@ from erpnext.education.api import enroll_student
class ProgramEnrollmentTool(Document):
def get_students(self):
students = []
if not self.get_students_from:
frappe.throw(_("Mandatory field - Get Students From"))
elif not self.program:

View File

@@ -462,7 +462,8 @@ class ProductionOrder(Document):
if reset_only_qty:
for d in self.get("required_items"):
d.required_qty = item_dict.get(d.item_code).get("qty")
if item_dict.get(d.item_code):
d.required_qty = item_dict.get(d.item_code).get("qty")
else:
for item in sorted(item_dict.values(), key=lambda d: d['idx']):
self.append('required_items', {

View File

@@ -310,6 +310,7 @@ class ProductionPlanningTool(Document):
}
"""
item_list = []
precision = frappe.get_precision("BOM Item", "stock_qty")
for bom, so_wise_qty in bom_dict.items():
bom_wise_item_details = {}
@@ -334,8 +335,9 @@ class ProductionPlanningTool(Document):
for item, item_details in bom_wise_item_details.items():
for so_qty in so_wise_qty:
item_list.append([item, flt(item_details.qty) * so_qty[1], item_details.description,
item_details.stock_uom, item_details.min_order_qty, so_qty[0]])
item_list.append([item, flt(flt(item_details.qty) * so_qty[1], precision),
item_details.description, item_details.stock_uom, item_details.min_order_qty,
so_qty[0]])
self.make_items_dict(item_list)

View File

@@ -35,4 +35,16 @@ def get_list_context(context):
context.title = 'All Chapters'
context.no_breadcrumbs = True
context.order_by = 'creation desc'
context.introduction = '<p>All Chapters</p>'
context.introduction = '<p>All Chapters</p>'
@frappe.whitelist()
def leave(title, user_id, leave_reason):
chapter = frappe.get_doc("Chapter", title)
for member in chapter.members:
if member.user == user_id:
member.enabled = 0
member.leave_reason = leave_reason
chapter.save(ignore_permissions=1)
frappe.db.commit()
return "Thank you for Feedback"

View File

@@ -5,34 +5,39 @@
<h3>Details</h3>
<p>{{ introduction }}</p>
{% if meetup_embed_html %}
{{ meetup_embed_html }}
{{ meetup_embed_html }}
{% endif %}
<h3>List of Members</h3>
{% if members %}
{% if members %}
<table class="table table-bordered small" style="max-width: 500px;">
<tr>
<th width="15%" ></th>
<th>Member Details</th>
</tr>
{% set index = [1] %}
{% for user in members %}
<tr>
<td>{{ loop.index }}</td>
<td>
<div class="row">
<div class="col-lg-6 col-md-6 col-sm-6">{{ frappe.db.get_value('User', user.user, 'full_name') }}</div>
<div class="col-lg-6 col-md-6 col-sm-6 text-right">
{% if user.website_url %}
<a href="{{ user.website_url }}">{{ user.website_url or '' }}</a>
{% if user.enabled == 1 %}
<tr>
<td>{{ index|length }}</td>
<td>
<div class="row">
<div class="col-lg-6 col-md-6 col-sm-6">{{ frappe.db.get_value('User', user.user, 'full_name') }}</div>
<div class="col-lg-6 col-md-6 col-sm-6 text-right">
{% if user.website_url %}
<a href="{{ user.website_url }}">{{ user.website_url or '' }}</a>
{% endif %}
</div>
<div class="col-lg-12">
{% if user.introduction %}
{{ user.introduction }}
{% endif %}
</div>
</div>
<div class="col-lg-12">
{% if user.introduction %}
{{ user.introduction }}
{% endif %}
</div>
</div>
</td>
</tr>
</td>
</tr>
{% set __ = index.append(1) %}
{% endif %}
{% endfor %}
</table>
{% else %}

View File

@@ -1,21 +1,30 @@
{% if doc.published %}
<div style="margin-bottom: 30px; max-width: 600px" class="with-border clickable">
<a href="/{{ doc.route }}">
<a href={{ route }}>
<h3>{{ doc.name }}</h3>
<p>
<span class="label">{{ frappe.db.get_value('User', chapter_head, 'full_name') }}</span>
<span class="label"> Chapter Head : {{ frappe.db.get_value('User', chapter_head, 'full_name') }} </span>
<span class="label">
{% if members %}
Members: {{ members|length }}
{% set index = [] %}
{% for user in members %}
{% if user.enabled == 1 %}
{% set __ = index.append(1) %}
{% endif %}
{% endfor %}
Members: {{ index|length }}
{% else %}
Members: 0
{% endif %}
</span>
</span>
<!-- Assignment of value to global variable not working in jinja -->
</p>
<p>{{ html2text(doc.introduction[:200]) }}{% if introduction|len > 200 %}...{% endif %}</p>
</a>
</div>
{% endif %}
<!-- this is a sample default list template -->
<style type="text/css">
.label {

View File

@@ -132,6 +132,36 @@
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "leave_reason",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Leave Reason",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}
],
"has_web_view": 0,
@@ -144,7 +174,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2017-12-06 11:33:34.300252",
"modified": "2018-01-12 12:16:10.591039",
"modified_by": "Administrator",
"module": "Non Profit",
"name": "Chapter Member",

View File

@@ -2,7 +2,7 @@
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"allow_rename": 1,
"autoname": "field:email",
"beta": 0,
"creation": "2017-09-19 16:20:27.510196",
@@ -295,7 +295,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-12-05 07:02:06.690416",
"modified": "2018-01-22 15:53:35.059946",
"modified_by": "Administrator",
"module": "Non Profit",
"name": "Donor",
@@ -330,6 +330,7 @@
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "donor_name",
"track_changes": 1,
"track_seen": 0
}

View File

@@ -2,7 +2,7 @@
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"allow_rename": 1,
"autoname": "field:email",
"beta": 0,
"creation": "2017-09-11 09:24:52.898356",
@@ -140,7 +140,7 @@
"collapsible": 0,
"columns": 0,
"fieldname": "email",
"fieldtype": "Data",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -151,6 +151,7 @@
"label": "Email",
"length": 0,
"no_copy": 0,
"options": "User",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -325,7 +326,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-12-05 07:03:21.606732",
"modified": "2018-01-22 15:58:46.507509",
"modified_by": "Administrator",
"module": "Non Profit",
"name": "Member",
@@ -380,6 +381,7 @@
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "member_name",
"track_changes": 1,
"track_seen": 0
}

View File

@@ -2,7 +2,7 @@
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"allow_rename": 1,
"autoname": "field:email",
"beta": 0,
"creation": "2017-09-19 16:16:45.676019",
@@ -506,7 +506,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-12-06 12:03:08.624579",
"modified": "2018-01-22 15:53:46.480182",
"modified_by": "Administrator",
"module": "Non Profit",
"name": "Volunteer",
@@ -540,6 +540,7 @@
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "volunteer_name",
"track_changes": 1,
"track_seen": 0
}

View File

@@ -484,4 +484,6 @@ erpnext.patches.v10_0.copy_projects_renamed_fields
erpnext.patches.v10_0.enabled_regional_print_format_based_on_country
erpnext.patches.v10_0.update_asset_calculate_depreciation
erpnext.patches.v10_0.add_guardian_role_for_parent_portal
erpnext.patches.v10_0.set_numeric_ranges_in_template_if_blank
erpnext.patches.v10_0.set_numeric_ranges_in_template_if_blank
erpnext.patches.v10_0.update_assessment_plan
erpnext.patches.v10_0.update_assessment_result

View File

@@ -0,0 +1,17 @@
# Copyright (c) 2017, Frappe and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
def execute():
frappe.reload_doc('education', 'doctype', 'assessment_plan')
frappe.db.sql("""
UPDATE `tabAssessment Plan` as ap
INNER JOIN `tabStudent Group` as sg ON sg.name = ap.student_group
SET ap.academic_term = sg.academic_term,
ap.academic_year = sg.academic_year,
ap.program = sg.program
WHERE ap.docstatus = 1
""")

View File

@@ -0,0 +1,20 @@
# Copyright (c) 2017, Frappe and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
def execute():
frappe.reload_doc('education', 'doctype', 'assessment_result')
frappe.db.sql("""
UPDATE `tabAssessment Result` AS ar
INNER JOIN `tabAssessment Plan` AS ap ON ap.name = ar.assessment_plan
SET ar.academic_term = ap.academic_term,
ar.academic_year = ap.academic_year,
ar.program = ap.program,
ar.course = ap.course,
ar.assessment_group = ap.assessment_group,
ar.student_group = ap.student_group
WHERE ap.docstatus = 1
""")

View File

@@ -16,7 +16,7 @@ def execute():
else:
company = frappe.db.get_single_value('Global Defaults', 'default_company')
time_sheet = make_timesheet(data.production_order)
time_sheet = make_timesheet(data.production_order, company)
args = get_timelog_data(data)
add_timesheet_detail(time_sheet, args)
if data.docstatus == 2:

View File

@@ -169,5 +169,8 @@ input[type=number]::-webkit-outer-spin-button {
height: 60px;
}
.grand-total .grand-total-value {
font-size: 24px;
font-size: 18px;
}
.rounded-total-value {
font-size: 18px;
}

View File

@@ -434,7 +434,8 @@ erpnext.taxes_and_totals = erpnext.payments.extend({
} else if (frappe.sys_defaults.disable_rounded_total) {
disable_rounded_total = frappe.sys_defaults.disable_rounded_total;
}
if(disable_rounded_total) {
if (cint(disable_rounded_total)) {
this.frm.doc.rounded_total = 0;
this.frm.doc.base_rounded_total = 0;
return;

View File

@@ -244,10 +244,11 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
method: "erpnext.controllers.accounts_controller.get_default_taxes_and_charges",
args: {
"master_doctype": taxes_and_charges_field.options,
"tax_template": me.frm.doc.taxes_and_charges,
"company": me.frm.doc.company
},
callback: function(r) {
if(!r.exc) {
if(!r.exc && r.message) {
frappe.run_serially([
() => {
// directly set in doc, so as not to call triggers
@@ -538,7 +539,8 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
// due_date is to be changed, payment terms template and/or payment schedule must
// be removed as due_date is automatically changed based on payment terms
if (this.frm.doc.due_date) {
if (this.frm.doc.payment_terms_template || this.frm.doc.payment_schedule.length) {
if (this.frm.doc.payment_terms_template ||
(this.frm.doc.payment_schedule && this.frm.doc.payment_schedule.length)) {
var message1 = "";
var message2 = "";
var final_message = "Please clear the ";
@@ -548,7 +550,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
final_message = final_message + message1;
}
if (this.frm.doc.payment_schedule.length) {
if ((this.frm.doc.payment_schedule || []).length) {
message2 = "Payment Schedule Table";
if (message1.length !== 0) message2 = " and " + message2;
final_message = final_message + message2;
@@ -647,6 +649,9 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
}
}).fail(() => this.frm.set_value('shipping_rule', ''));
}
else {
me.calculate_taxes_and_totals();
}
},
set_actual_charges_based_on_currency: function() {
@@ -1260,11 +1265,14 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
payment_terms_template: function() {
var me = this;
if(this.frm.doc.payment_terms_template) {
var posting_date = this.frm.doc.bill_date ||
this.frm.doc.posting_date || this.frm.doc.transaction_date;
frappe.call({
method: "erpnext.controllers.accounts_controller.get_payment_terms",
args: {
terms_template: this.frm.doc.payment_terms_template,
posting_date: this.frm.doc.posting_date || this.frm.doc.transaction_date,
posting_date: posting_date,
grand_total: this.frm.doc.rounded_total || this.frm.doc.grand_total
},
callback: function(r) {

View File

@@ -216,6 +216,10 @@ input[type=number]::-webkit-outer-spin-button {
}
.grand-total-value {
font-size: 24px;
font-size: 18px;
}
}
.rounded-total-value {
font-size: 18px;
}

View File

@@ -66,7 +66,7 @@ class Customer(TransactionBase):
self.create_lead_address_contact()
def create_primary_contact(self):
if not self.customer_primary_contact:
if not self.customer_primary_contact and not self.lead_name:
if self.mobile_no or self.email_id:
contact = make_contact(self)
self.db_set('customer_primary_contact', contact.name)
@@ -146,7 +146,8 @@ class Customer(TransactionBase):
frappe.throw(_("A Customer Group exists with same name please change the Customer name or rename the Customer Group"), frappe.NameError)
def validate_credit_limit_on_change(self):
if self.get("__islocal") or self.credit_limit == frappe.db.get_value("Customer", self.name, "credit_limit"):
if self.get("__islocal") or not self.credit_limit \
or self.credit_limit == frappe.db.get_value("Customer", self.name, "credit_limit"):
return
for company in frappe.get_all("Company"):

View File

@@ -82,8 +82,8 @@ erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({
get_query_filters: {
status: ["not in", ["Lost", "Closed"]],
company: me.frm.doc.company,
// cannot set enquiry_type as setter, as the fieldname is order_type
enquiry_type: me.frm.doc.order_type,
// cannot set opportunity_type as setter, as the fieldname is order_type
opportunity_type: me.frm.doc.order_type,
}
})
}, __("Get items from"), "btn-default");

View File

@@ -585,16 +585,28 @@ class POSCart {
this.wrapper.find('.grand-total-value').text(
format_currency(this.frm.doc.grand_total, this.frm.currency));
this.wrapper.find('.rounded-total-value').text(
format_currency(this.frm.doc.rounded_total, this.frm.currency));
const customer = this.frm.doc.customer;
this.customer_field.set_value(customer);
}
get_grand_total() {
let total = this.get_total_template('Grand Total', 'grand-total-value');
if (!cint(frappe.sys_defaults.disable_rounded_total)) {
total += this.get_total_template('Rounded Total', 'rounded-total-value');
}
return total;
}
get_total_template(label, class_name) {
return `
<div class="list-item">
<div class="list-item__content text-muted">${__('Grand Total')}</div>
<div class="list-item__content list-item__content--flex-2 grand-total-value">0.00</div>
<div class="list-item__content text-muted">${__(label)}</div>
<div class="list-item__content list-item__content--flex-2 ${class_name}">0.00</div>
</div>
`;
}
@@ -671,6 +683,10 @@ class POSCart {
this.$grand_total.find('.grand-total-value').text(
format_currency(this.frm.doc.grand_total, this.frm.currency)
);
this.$grand_total.find('.rounded-total-value').text(
format_currency(this.frm.doc.rounded_total, this.frm.currency)
);
}
make_customer_field() {
@@ -1381,7 +1397,8 @@ class Payment {
set_title() {
let title = __('Total Amount {0}',
[format_currency(this.frm.doc.grand_total, this.frm.doc.currency)]);
[format_currency(this.frm.doc.rounded_total || this.frm.doc.grand_total,
this.frm.doc.currency)]);
this.dialog.set_title(title);
}

View File

@@ -41,8 +41,9 @@ def get_columns():
def get_product_bundle_items():
sbom_item_map = {}
for sbom in frappe.db.sql("""select parent, item_code, qty from `tabProduct Bundle Item`
where docstatus < 2""", as_dict=1):
for sbom in frappe.db.sql("""select pb.new_item_code as parent, pbi.item_code, pbi.qty
from `tabProduct Bundle Item` as pbi, `tabProduct Bundle` as pb
where pb.docstatus < 2 and pb.name = pbi.parent""", as_dict=1):
sbom_item_map.setdefault(sbom.parent, {}).setdefault(sbom.item_code, sbom.qty)
return sbom_item_map

View File

@@ -32,6 +32,10 @@ frappe.ui.form.on("Company", {
frm.toggle_enable("default_currency", (frm.doc.__onload &&
!frm.doc.__onload.transactions_exist));
frm.add_custom_button(__('Make Tax Template'), function() {
frm.trigger("make_default_tax_template");
});
frm.add_custom_button(__('Cost Centers'), function() {
frappe.set_route('Tree', 'Cost Center', {'company': frm.doc.name})
}, __("View"));
@@ -47,13 +51,6 @@ frappe.ui.form.on("Company", {
frm.add_custom_button(__('Purchase Tax Template'), function() {
frappe.set_route('List', 'Purchase Taxes and Charges Template', {'company': frm.doc.name});
}, __("View"));
frm.add_custom_button(__('Default Tax Template'), function() {
frm.trigger("make_default_tax_template");
}, __("Make"));
frm.page.set_inner_btn_group_as_primary(__("View"));
frm.page.set_inner_btn_group_as_primary(__("Make"));
}
erpnext.company.set_chart_of_accounts_options(frm.doc);

View File

@@ -34,6 +34,7 @@ class Company(Document):
self.validate_currency()
self.validate_coa_input()
self.validate_perpetual_inventory()
self.check_country_change()
def validate_abbr(self):
if not self.abbr:
@@ -80,9 +81,12 @@ class Company(Document):
if not frappe.db.sql("""select name from tabAccount
where company=%s and docstatus<2 limit 1""", self.name):
if not frappe.local.flags.ignore_chart_of_accounts:
frappe.flags.country_change = True
self.create_default_accounts()
self.create_default_warehouses()
install_country_fixtures(self.name)
if frappe.flags.country_change:
install_country_fixtures(self.name)
if not frappe.db.get_value("Cost Center", {"is_group": 0, "company": self.name}):
self.create_default_cost_center()
@@ -147,6 +151,13 @@ class Company(Document):
frappe.msgprint(_("Set default inventory account for perpetual inventory"),
alert=True, indicator='orange')
def check_country_change(self):
frappe.flags.country_change = False
if not self.get('__islocal') and \
self.country != frappe.db.get_value('Company', self.name, 'country'):
frappe.flags.country_change = True
def set_default_accounts(self):
self._set_default_account("default_cash_account", "Cash")
self._set_default_account("default_bank_account", "Bank")
@@ -162,8 +173,14 @@ class Company(Document):
self._set_default_account("default_expense_account", "Cost of Goods Sold")
if not self.default_income_account:
self.db_set("default_income_account", frappe.db.get_value("Account",
{"account_name": _("Sales"), "company": self.name}))
income_account = frappe.db.get_value("Account",
{"account_name": _("Sales"), "company": self.name, "is_group": 0})
if not income_account:
income_account = frappe.db.get_value("Account",
{"account_name": _("Sales Account"), "company": self.name})
self.db_set("default_income_account", income_account)
if not self.default_payable_account:
self.db_set("default_payable_account", self.default_payable_account)
@@ -281,6 +298,15 @@ class Company(Document):
# delete mode of payment account
frappe.db.sql("delete from `tabMode of Payment Account` where company=%s", self.name)
# delete BOMs
boms = frappe.db.sql_list("select name from tabBOM where company=%s", self.name)
if boms:
frappe.db.sql("delete from tabBOM where company=%s", self.name)
for dt in ("BOM Operation", "BOM Item", "BOM Scrap Item", "BOM Explosion Item"):
frappe.db.sql("delete from `tab%s` where parent in (%s)"""
% (dt, ', '.join(['%s']*len(boms))), tuple(boms))
frappe.db.sql("delete from tabEmployee where company=%s", self.name)
@frappe.whitelist()
def enqueue_replace_abbr(company, old, new):
@@ -349,7 +375,6 @@ def update_company_current_month_sales(company):
monthly_total = results[0]['total'] if len(results) > 0 else 0
frappe.db.set_value("Company", company, "total_monthly_sales", monthly_total)
frappe.db.commit()
def update_company_monthly_sales(company):
'''Cache past year monthly sales of every company based on sales invoices'''
@@ -360,7 +385,6 @@ def update_company_monthly_sales(company):
"posting_date", filter_str, "sum")
frappe.db.set_value("Company", company, "sales_monthly_history", json.dumps(month_to_value_dict))
frappe.db.commit()
def cache_companies_monthly_sales_history():
companies = [d['name'] for d in frappe.get_list("Company")]

View File

@@ -204,7 +204,6 @@ def _get_cart_quotation(party=None):
"status": "Draft",
"docstatus": 0,
"__islocal": 1,
"payment_terms_template": "_Test Payment Term Template",
(party.doctype.lower()): party.name
})

View File

@@ -9,7 +9,7 @@ from erpnext.shopping_cart.cart import _get_cart_quotation, update_cart, get_par
from erpnext.tests.utils import create_test_contact_and_address
test_dependencies = ['Payment Terms Template']
# test_dependencies = ['Payment Terms Template']
class TestShoppingCart(unittest.TestCase):
"""

View File

@@ -106,6 +106,13 @@ frappe.ui.form.on("Item", {
frappe.set_route("Form", "Item Variant Settings");
}, __("View"));
}
const stock_exists = (frm.doc.__onload
&& frm.doc.__onload.stock_exists) ? 1 : 0;
['has_serial_no', 'has_batch_no'].forEach((fieldname) => {
frm.set_df_property(fieldname, 'read_only', stock_exists);
});
},
validate: function(frm){

View File

@@ -1180,7 +1180,7 @@
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 1,
"set_only_once": 0,
"unique": 0
},
{
@@ -1370,7 +1370,7 @@
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 1,
"set_only_once": 0,
"unique": 0
},
{
@@ -3453,7 +3453,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 1,
"modified": "2017-12-27 15:47:17.039337",
"modified": "2018-01-23 12:21:16.641517",
"modified_by": "Administrator",
"module": "Stock",
"name": "Item",

View File

@@ -170,6 +170,8 @@ erpnext.buying.MaterialRequestController = erpnext.buying.BuyingController.exten
d.description = item.description;
d.warehouse = values.warehouse;
d.uom = item.stock_uom;
d.stock_uom = item.stock_uom;
d.conversion_factor = 1;
d.qty = item.qty;
});
}
@@ -282,4 +284,4 @@ function set_schedule_date(frm) {
if(frm.doc.schedule_date){
erpnext.utils.copy_value_in_all_row(frm.doc, frm.doc.doctype, frm.doc.name, "items", "schedule_date");
}
}
}

View File

@@ -48,7 +48,7 @@ cur_frm.cscript.validate = function(doc, cdt, cdn) {
cur_frm.cscript.validate_case_nos = function(doc) {
doc = locals[doc.doctype][doc.name];
if(cint(doc.from_case_no)==0) {
frappe.msgprint(__("Case No. cannot be 0"))
frappe.msgprint(__("The 'From Package No.' field must neither be empty nor it's value less than 1."));
frappe.validated = false;
} else if(!cint(doc.to_case_no)) {
doc.to_case_no = doc.from_case_no;
@@ -124,3 +124,5 @@ cur_frm.pformat.net_weight_pkg= function(doc){
cur_frm.pformat.gross_weight_pkg= function(doc){
return '<table style="width:100%">' + make_row('Gross Weight', doc.gross_weight_pkg) + '</table>'
}
// TODO: validate gross weight field

View File

@@ -72,6 +72,7 @@ frappe.ui.form.on('Stock Entry', {
mr_item.item_code = item.item_code;
mr_item.item_name = item.item_name;
mr_item.uom = item.uom;
mr_item.conversion_factor = item.conversion_factor;
mr_item.item_group = item.item_group;
mr_item.description = item.description;
mr_item.image = item.image;

View File

@@ -150,7 +150,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Disabled",
"length": 0,
@@ -699,7 +699,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-08-21 02:12:33.652689",
"modified": "2018-01-23 16:45:45.546649",
"modified_by": "Administrator",
"module": "Stock",
"name": "Warehouse",

View File

@@ -85,18 +85,22 @@ def get_item_warehouse_projected_qty(items_to_consider):
from tabBin where item_code in ({0})
and (warehouse != "" and warehouse is not null)"""\
.format(", ".join(["%s"] * len(items_to_consider))), items_to_consider):
item_warehouse_projected_qty.setdefault(item_code, {})[warehouse] = flt(projected_qty)
if item_code not in item_warehouse_projected_qty:
item_warehouse_projected_qty.setdefault(item_code, {})
if warehouse not in item_warehouse_projected_qty.get(item_code):
item_warehouse_projected_qty[item_code][warehouse] = flt(projected_qty)
warehouse_doc = frappe.get_doc("Warehouse", warehouse)
while warehouse_doc.parent_warehouse:
if not item_warehouse_projected_qty.get(item_code, {}).get(warehouse_doc.parent_warehouse):
item_warehouse_projected_qty.setdefault(item_code, {})[warehouse_doc.parent_warehouse] = flt(projected_qty)
else:
item_warehouse_projected_qty[item_code][warehouse_doc.parent_warehouse] += flt(projected_qty)
warehouse_doc = frappe.get_doc("Warehouse", warehouse_doc.parent_warehouse)
return item_warehouse_projected_qty
def create_material_request(material_requests):

View File

@@ -12,13 +12,52 @@ def execute(filters=None):
def get_columns():
return [
_("Item Name") + ":Link/Item:150",
_("Warehouse") + ":Link/Warehouse:130",
_("Stock Available") + ":Float:120",
_("Buying Price List") + ":Data:130",
_("Buying Rate") + ":Currency:110",
_("Selling Price List") + ":Data:130",
_("Selling Rate") + ":Currency:110"
{
"label": _("Item Name"),
"fieldname": "item_name",
"fieldtype": "Link",
"options": "Item",
"width": 120
},
{
"label": _("Warehouse"),
"fieldname": "warehouse",
"fieldtype": "Link",
"options": "Warehouse",
"width": 120
},
{
"label": _("Stock Available"),
"fieldname": "stock_available",
"fieldtype": "Float",
"width": 120
},
{
"label": _("Buying Price List"),
"fieldname": "buying_price_list",
"fieldtype": "Link",
"options": "Price List",
"width": 120
},
{
"label": _("Buying Rate"),
"fieldname": "buying_rate",
"fieldtype": "Currency",
"width": 120
},
{
"label": _("Selling Price List"),
"fieldname": "selling_price_list",
"fieldtype": "Link",
"options": "Price List",
"width": 120
},
{
"label": _("Selling Rate"),
"fieldname": "selling_rate",
"fieldtype": "Currency",
"width": 120
}
]
def get_data(filters, columns):
@@ -27,72 +66,72 @@ def get_data(filters, columns):
return item_price_qty_data
def get_item_price_qty_data(filters):
item_dicts = []
conditions = ""
if filters.get("item_code"):
conditions += "where a.item_code=%(item_code)s"
item_results = frappe.db.sql("""select a.item_code as name,a.name as price_list_name,
b.warehouse as warehouse,b.actual_qty as actual_qty
item_results = frappe.db.sql("""select a.item_code as item_name, a.name as price_list_name,
b.warehouse as warehouse, b.actual_qty as actual_qty
from `tabItem Price` a left join `tabBin` b
ON a.item_code = b.item_code
{conditions}"""
.format(conditions=conditions), filters, as_dict=1)
price_list_names = ",".join(['"' + frappe.db.escape(item['price_list_name']) + '"'
for item in item_results])
price_list_names = list(set([frappe.db.escape(item.price_list_name) for item in item_results]))
buying_price_map = get_buying_price_map(price_list_names)
selling_price_map = get_selling_price_map(price_list_names)
buying_price_map = get_price_map(price_list_names, buying=1)
selling_price_map = get_price_map(price_list_names, selling=1)
item_dicts = [{"Item Name": d['name'],"Item Price List": d['price_list_name'],"Warehouse": d['warehouse'],
"Stock Available": d['actual_qty']} for d in item_results]
for item_dict in item_dicts:
price_list = item_dict["Item Price List"]
item_dict["Warehouse"] = item_dict["Warehouse"] or ""
item_dict["Stock Available"] = item_dict["Stock Available"] or 0
if buying_price_map.get(price_list):
item_dict["Buying Price List"] = buying_price_map.get(price_list)["Buying Price List"] or ""
item_dict["Buying Rate"] = buying_price_map.get(price_list)["Buying Rate"] or 0
if selling_price_map.get(price_list):
item_dict["Selling Price List"] = selling_price_map.get(price_list)["Selling Price List"] or ""
item_dict["Selling Rate"] = selling_price_map.get(price_list)["Selling Rate"] or 0
return item_dicts
result = []
if item_results:
for item_dict in item_results:
data = {
'item_name': item_dict.item_name,
'warehouse': item_dict.warehouse,
'stock_available': item_dict.actual_qty or 0,
'buying_price_list': "",
'buying_rate': 0.0,
'selling_price_list': "",
'selling_rate': 0.0
}
def get_buying_price_map(price_list_names):
buying_price = frappe.db.sql("""
price_list = item_dict["price_list_name"]
if buying_price_map.get(price_list):
data["buying_price_list"] = buying_price_map.get(price_list)["Buying Price List"] or ""
data["buying_rate"] = buying_price_map.get(price_list)["Buying Rate"] or 0
if selling_price_map.get(price_list):
data["selling_price_list"] = selling_price_map.get(price_list)["Selling Price List"] or ""
data["selling_rate"] = selling_price_map.get(price_list)["Selling Rate"] or 0
result.append(data)
return result
def get_price_map(price_list_names, buying=0, selling=0):
price_map = {}
if not price_list_names:
return price_map
rate_key = "Buying Rate" if buying else "Selling Rate"
price_list_key = "Buying Price List" if buying else "Selling Price List"
price_list_condition = " and buying=1" if buying else " and selling=1"
pricing_details = frappe.db.sql("""
select
name,price_list,price_list_rate
from
`tabItem Price`
where
name in ({price_list_names}) and buying=1
""".format(price_list_names=price_list_names), as_dict=1)
name in ({price_list_names}) {price_list_condition}
""".format(price_list_names=', '.join(['%s']*len(price_list_names)),
price_list_condition=price_list_condition), price_list_names, as_dict=1)
buying_price_map = {}
for d in buying_price:
for d in pricing_details:
name = d["name"]
buying_price_map[name] = {
"Buying Price List" :d["price_list"],
"Buying Rate" :d["price_list_rate"]
price_map[name] = {
price_list_key :d["price_list"],
rate_key :d["price_list_rate"]
}
return buying_price_map
def get_selling_price_map(price_list_names):
selling_price = frappe.db.sql("""
select
name,price_list,price_list_rate
from
`tabItem Price`
where
name in ({price_list_names}) and selling=1
""".format(price_list_names=price_list_names), as_dict=1)
selling_price_map = {}
for d in selling_price:
name = d["name"]
selling_price_map[name] = {
"Selling Price List" :d["price_list"],
"Selling Rate" :d["price_list_rate"]
}
return selling_price_map
return price_map

View File

@@ -144,10 +144,9 @@ def get_incoming_rate(args):
if not in_rate:
voucher_no = args.get('voucher_no') or args.get('name')
in_rate = get_valuation_rate(args.get('item_code'), args.get('warehouse'),
args.get('voucher_type'), voucher_no, args.get('allow_zero_valuation'),
currency=erpnext.get_company_currency(args.get('company')))
currency=erpnext.get_company_currency(args.get('company')), company=args.get('company'))
return in_rate

View File

@@ -659,7 +659,7 @@
"columns": 0,
"depends_on": "eval:!doc.__islocal",
"fieldname": "resolution_details",
"fieldtype": "Small Text",
"fieldtype": "Text Editor",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -879,7 +879,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-11-15 17:15:40.347362",
"modified": "2018-01-11 07:10:53.707415",
"modified_by": "Administrator",
"module": "Support",
"name": "Issue",

View File

@@ -11,18 +11,18 @@
<p><a href="/login?redirect-to=/{{ chapter.route }}" class='btn btn-primary'>Login</a></p>
{% else %}
{% if already_member %}
<p>You are already a member of {{ chapter.title }}!</p>
<p>You are already a member of {{ chapter.name }}!</p>
{{ chapter_button() }}
<p><a href="">Leave Chapter</a></p>
{% else %}
{% if frappe.local.request.method=='POST' %}
<p>Welcome to chapter {{ chapter.title }}!</p>
<p>Welcome to chapter {{ chapter.name }}!</p>
{{ chapter_button() }}
{% else %}
<div style="padding: 20px 0;">
<div class="row">
<div class="col-lg-8 col-md-8">
<form name="user-intro" action="/join-chapter" method='POST'>
<form name="user-intro" action="/non_profit/join-chapter" method='POST'>
<div class="form-group">
<input name="name" class="hidden form-control" type="text"
value="{{chapter.name}}">

View File

@@ -4,7 +4,7 @@ def get_context(context):
context.no_cache = True
chapter = frappe.get_doc('Chapter', frappe.form_dict.name)
if frappe.session.user!='Guest':
if frappe.session.user in [d.user for d in chapter.members]:
if frappe.session.user in [d.user for d in chapter.members if d.enabled == 1]:
context.already_member = True
else:
if frappe.request.method=='GET':

View File

@@ -1,16 +1,42 @@
{% extends "templates/web.html" %}
<!--
{% macro chapter_button() %}
<p><a href="/{{ chapter.route }}" class='btn btn-primary'>
Go to Chapter Page</a></p>
{% endmacro %}
-->
{% block page_content %}
{% if member_deleted %}
<p>You are not a member of {{ chapter.title }}!</p>
<p>You are not a member of {{ chapter.name }}!</p>
<div>
<form>
<div class="form-group">
<label for="leave">Why do you want to leave this chapter</label>
<input type="text" name="leave" class="form-control" id="leave">
</div>
<button type="button" class="btn btn-default btn-leave" data-title= "{{ chapter.name }}" id="btn-leave">Submit
</button>
</form>
</div>
<p>Please signup and login to join this chapter</p>
<p><a href="/join-chapter?name={{ chapter.name }}" class='btn btn-primary'>Become Member agian</a></p>
{% endif %}
<script>
frappe.ready(function() {
$(".btn-leave").on("click", function() {
var leave = $("#leave").val();
var user_id = frappe.session.user;
var title = $(this).attr("data-title");
frappe.call({
method: "erpnext.non_profit.doctype.chapter.chapter.leave",
args: {
leave_reason: leave,
user_id: user_id,
title: title
},
callback: function(r) {
if(r.message) {
frappe.msgprint(r.message)
}
}
})
});
})
</script>
{% endblock %}

View File

@@ -3,13 +3,5 @@ import frappe
def get_context(context):
context.no_cache = True
chapter = frappe.get_doc('Chapter', frappe.form_dict.name)
# if frappe.session.user!='Guest':
if frappe.session.user in [d.user for d in chapter.members]:
user = frappe.session.user
parent = frappe.form_dict.name
frappe.db.sql("""delete from `tabChapter Member` where parent = %s and user = %s """, (parent, user))
frappe.db.commit()
context.member_deleted = True
context.chapter = chapter

View File

@@ -1,7 +1,7 @@
<div class="row">
{% if doc.flags.show_inclusive_tax_in_print %}
<div class="col-xs-5 {%- if doc._align_labels_right %} text-right{%- endif -%}">
<label>{{ _("Total Excl. Tax") }}</label></div>
<label>{{ _("Total (Without Tax)") }}</label></div>
<div class="col-xs-7 text-right">
{{ doc.get_formatted("net_total", doc) }}
</div>
@@ -12,4 +12,4 @@
{{ doc.get_formatted("total", doc) }}
</div>
{% endif %}
</div>
</div>

View File

@@ -5,7 +5,7 @@ from __future__ import unicode_literals
import frappe
import frappe.share
from frappe import _
from frappe.utils import cstr, now_datetime, cint, flt
from frappe.utils import cstr, now_datetime, cint, flt, get_time
from erpnext.controllers.status_updater import StatusUpdater
class UOMMustBeIntegerError(frappe.ValidationError): pass
@@ -26,6 +26,11 @@ class TransactionBase(StatusUpdater):
now = now_datetime()
self.posting_date = now.strftime('%Y-%m-%d')
self.posting_time = now.strftime('%H:%M:%S.%f')
elif self.posting_time:
try:
get_time(self.posting_time)
except ValueError:
frappe.throw(_('Invalid Posting Time'))
def add_calendar_event(self, opts, force=False):
if cstr(self.contact_by) != cstr(self._prev.contact_by) or \

View File

@@ -40,7 +40,7 @@ def create_customers(args_data):
@frappe.whitelist()
def create_letterhead(args_data):
args = json.loads(args_data)
letterhead = args.get("letterhead")
letterhead = args.get("letterhead").encode('utf-8')
if letterhead:
try:
frappe.get_doc({