Merge branch 'v12-pre-release' into version-12
This commit is contained in:
commit
6d9a300a85
47
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
47
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Report a bug encountered while using ERPNext
|
||||
labels: bug
|
||||
---
|
||||
|
||||
<!--
|
||||
Welcome to ERPNext issue tracker! Before creating an issue, please heed the following:
|
||||
|
||||
1. This tracker should only be used to report bugs and request features / enhancements to ERPNext
|
||||
- For questions and general support, checkout the manual https://erpnext.com/docs/user/manual/en or use https://discuss.erpnext.com
|
||||
- For documentation issues, refer to https://github.com/frappe/erpnext_com
|
||||
2. Use the search function before creating a new issue. Duplicates will be closed and directed to
|
||||
the original discussion.
|
||||
3. When making a bug report, make sure you provide all required information. The easier it is for
|
||||
maintainers to reproduce, the faster it'll be fixed.
|
||||
4. If you think you know what the reason for the bug is, share it with us. Maybe put in a PR 😉
|
||||
-->
|
||||
|
||||
## Description of the issue
|
||||
|
||||
## Context information (for bug reports)
|
||||
|
||||
**Output of `bench version`**
|
||||
```
|
||||
(paste here)
|
||||
```
|
||||
|
||||
## Steps to reproduce the issue
|
||||
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
|
||||
### Observed result
|
||||
|
||||
### Expected result
|
||||
|
||||
### Stacktrace / full error message
|
||||
|
||||
```
|
||||
(paste here)
|
||||
```
|
||||
|
||||
## Additional information
|
||||
|
||||
OS version / distribution, `ERPNext` install method, etc.
|
28
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
28
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea to improve ERPNext
|
||||
labels: feature-request
|
||||
---
|
||||
|
||||
<!--
|
||||
Welcome to ERPNext issue tracker! Before creating an issue, please heed the following:
|
||||
|
||||
1. This tracker should only be used to report bugs and request features / enhancements to ERPNext
|
||||
- For questions and general support, checkout the manual https://erpnext.com/docs/user/manual/en or use https://discuss.erpnext.com
|
||||
- For documentation issues, refer to https://github.com/frappe/erpnext_com
|
||||
2. Use the search function before creating a new issue. Duplicates will be closed and directed to
|
||||
the original discussion.
|
||||
3. When making a feature request, make sure to be as verbose as possible. The better you convey your message, the greater the drive to make it happen.
|
||||
-->
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
17
.github/ISSUE_TEMPLATE/question-about-using-erpnext.md
vendored
Normal file
17
.github/ISSUE_TEMPLATE/question-about-using-erpnext.md
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
name: Question about using ERPNext
|
||||
about: This is not the appropriate channel
|
||||
labels: invalid
|
||||
---
|
||||
|
||||
Please post on our forums:
|
||||
|
||||
for questions about using `ERPNext`: https://discuss.erpnext.com
|
||||
|
||||
for questions about using the `Frappe Framework`: https://discuss.frappe.io
|
||||
|
||||
for questions about using `bench`, probably the best place to start is the [bench repo](https://github.com/frappe/bench)
|
||||
|
||||
For documentation issues, use the [ERPNext Documentation](https://erpnext.com/docs/) or [Frappe Framework Documentation](https://frappe.io/docs/user/en) or the [developer cheetsheet](https://github.com/frappe/frappe/wiki/Developer-Cheatsheet)
|
||||
|
||||
> **Posts that are not bug reports or feature requests will not be addressed on this issue tracker.**
|
33
.github/PULL_REQUEST_TEMPLATE.md
vendored
33
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,2 +1,33 @@
|
||||
Please read the pull request checklist to make sure your changes are merged: https://github.com/frappe/erpnext/wiki/Pull-Request-Checklist
|
||||
<!--
|
||||
|
||||
Some key notes before you open a PR:
|
||||
|
||||
1. Select which branch should this PR be merged in?
|
||||
2. PR name follows [convention](http://karma-runner.github.io/4.0/dev/git-commit-msg.html)
|
||||
3. All tests pass locally, UI and Unit tests
|
||||
4. All business logic and validations must be on the server-side
|
||||
5. Update necessary Documentation
|
||||
6. Put `closes #XXXX` in your comment to auto-close the issue that your PR fixes
|
||||
|
||||
|
||||
Also, if you're new here
|
||||
|
||||
- Documentation Guidelines => https://github.com/frappe/erpnext/wiki/Updating-Documentation
|
||||
|
||||
- Contribution Guide => https://github.com/frappe/erpnext/blob/develop/.github/CONTRIBUTING.md
|
||||
|
||||
- Pull Request Checklist => https://github.com/frappe/erpnext/wiki/Pull-Request-Checklist
|
||||
|
||||
-->
|
||||
|
||||
> Please provide enough information so that others can review your pull request:
|
||||
|
||||
<!-- You can skip this if you're fixing a typo or updating existing documentation -->
|
||||
|
||||
> Explain the **details** for making this change. What existing problem does the pull request solve?
|
||||
|
||||
<!-- Example: When "Adding a function to do X", explain why it is necessary to have a way to do X. -->
|
||||
|
||||
> Screenshots/GIFs
|
||||
|
||||
<!-- Add images/recordings to better visualize the change: expected/current behviour -->
|
||||
|
7
SECURITY.md
Normal file
7
SECURITY.md
Normal file
@ -0,0 +1,7 @@
|
||||
# Security Policy
|
||||
|
||||
The ERPNext team and community take security issues seriously. To report a security issue, fill out the form at [https://erpnext.com/security/report](https://erpnext.com/security/report).
|
||||
|
||||
You can help us make ERPNext and all it's users more secure by following the [Reporting guidelines](https://erpnext.com/security).
|
||||
|
||||
We appreciate your efforts to responsibly disclose your findings. We'll endeavor to respond quickly, and will keep you updated throughout the process.
|
@ -5,7 +5,7 @@ import frappe
|
||||
from erpnext.hooks import regional_overrides
|
||||
from frappe.utils import getdate
|
||||
|
||||
__version__ = '12.1.6'
|
||||
__version__ = '12.1.7'
|
||||
|
||||
def get_default_company(user=None):
|
||||
'''Get default company for user'''
|
||||
|
@ -188,7 +188,6 @@
|
||||
"label": "Include in gross"
|
||||
},
|
||||
{
|
||||
"bold": 1,
|
||||
"default": "0",
|
||||
"fieldname": "disabled",
|
||||
"fieldtype": "Check",
|
||||
@ -197,7 +196,7 @@
|
||||
],
|
||||
"icon": "fa fa-money",
|
||||
"idx": 1,
|
||||
"modified": "2019-08-23 03:40:58.441295",
|
||||
"modified": "2019-10-10 19:10:02.967554",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Account",
|
||||
|
@ -20,7 +20,7 @@ frappe.ui.form.on('Bank Account', {
|
||||
},
|
||||
refresh: function(frm) {
|
||||
frappe.dynamic_link = { doc: frm.doc, fieldname: 'name', doctype: 'Bank Account' }
|
||||
|
||||
|
||||
frm.toggle_display(['address_html','contact_html'], !frm.doc.__islocal);
|
||||
|
||||
if (frm.doc.__islocal) {
|
||||
@ -37,5 +37,9 @@ frappe.ui.form.on('Bank Account', {
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
is_company_account: function(frm) {
|
||||
frm.set_df_property('account', 'reqd', frm.doc.is_company_account);
|
||||
}
|
||||
});
|
||||
|
File diff suppressed because it is too large
Load Diff
0
erpnext/accounts/doctype/coupon_code/__init__.py
Normal file
0
erpnext/accounts/doctype/coupon_code/__init__.py
Normal file
35
erpnext/accounts/doctype/coupon_code/coupon_code.js
Normal file
35
erpnext/accounts/doctype/coupon_code/coupon_code.js
Normal file
@ -0,0 +1,35 @@
|
||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Coupon Code', {
|
||||
coupon_name:function(frm){
|
||||
if (frm.doc.__islocal===1) {
|
||||
frm.trigger("make_coupon_code");
|
||||
}
|
||||
},
|
||||
coupon_type:function(frm){
|
||||
if (frm.doc.__islocal===1) {
|
||||
frm.trigger("make_coupon_code");
|
||||
}
|
||||
},
|
||||
make_coupon_code: function(frm) {
|
||||
var coupon_name=frm.doc.coupon_name;
|
||||
var coupon_code;
|
||||
if (frm.doc.coupon_type=='Gift Card') {
|
||||
coupon_code=Math.random().toString(12).substring(2, 12).toUpperCase();
|
||||
}
|
||||
else if(frm.doc.coupon_type=='Promotional'){
|
||||
coupon_name=coupon_name.replace(/\s/g,'');
|
||||
coupon_code=coupon_name.toUpperCase().slice(0,8);
|
||||
}
|
||||
frm.doc.coupon_code=coupon_code;
|
||||
frm.refresh_field('coupon_code');
|
||||
},
|
||||
refresh: function(frm) {
|
||||
if (frm.doc.pricing_rule) {
|
||||
frm.add_custom_button(__("Add/Edit Coupon Conditions"), function(){
|
||||
frappe.set_route("Form", "Pricing Rule", frm.doc.pricing_rule);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
175
erpnext/accounts/doctype/coupon_code/coupon_code.json
Normal file
175
erpnext/accounts/doctype/coupon_code/coupon_code.json
Normal file
@ -0,0 +1,175 @@
|
||||
{
|
||||
"allow_import": 1,
|
||||
"autoname": "field:coupon_name",
|
||||
"creation": "2018-01-22 14:34:39.701832",
|
||||
"doctype": "DocType",
|
||||
"document_type": "Other",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"coupon_name",
|
||||
"coupon_type",
|
||||
"customer",
|
||||
"column_break_4",
|
||||
"coupon_code",
|
||||
"pricing_rule",
|
||||
"uses",
|
||||
"valid_from",
|
||||
"valid_upto",
|
||||
"maximum_use",
|
||||
"used",
|
||||
"column_break_11",
|
||||
"description",
|
||||
"amended_from"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "coupon_name",
|
||||
"fieldtype": "Data",
|
||||
"label": "Coupon Name",
|
||||
"reqd": 1,
|
||||
"unique": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "coupon_type",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Coupon Type",
|
||||
"options": "Promotional\nGift Card",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: doc.coupon_type == \"Gift Card\"",
|
||||
"fieldname": "customer",
|
||||
"fieldtype": "Link",
|
||||
"label": "Customer",
|
||||
"options": "Customer"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_4",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"description": "To be used to get discount",
|
||||
"fieldname": "coupon_code",
|
||||
"fieldtype": "Data",
|
||||
"label": "Coupon Code",
|
||||
"no_copy": 1,
|
||||
"set_only_once": 1,
|
||||
"unique": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "pricing_rule",
|
||||
"fieldtype": "Link",
|
||||
"label": "Pricing Rule",
|
||||
"options": "Pricing Rule"
|
||||
},
|
||||
{
|
||||
"fieldname": "uses",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Uses"
|
||||
},
|
||||
{
|
||||
"fieldname": "valid_from",
|
||||
"fieldtype": "Date",
|
||||
"in_list_view": 1,
|
||||
"label": "Valid From"
|
||||
},
|
||||
{
|
||||
"fieldname": "valid_upto",
|
||||
"fieldtype": "Date",
|
||||
"label": "Valid Upto"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: doc.coupon_type == \"Promotional\"",
|
||||
"fieldname": "maximum_use",
|
||||
"fieldtype": "Int",
|
||||
"label": "Maximum Use"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "used",
|
||||
"fieldtype": "Int",
|
||||
"label": "Used",
|
||||
"no_copy": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_11",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Text Editor",
|
||||
"label": "Coupon Description"
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Link",
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"options": "Coupon Code",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"modified": "2019-10-15 14:12:22.686986",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Coupon Code",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts User",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Sales Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Website Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "coupon_name",
|
||||
"track_changes": 1
|
||||
}
|
25
erpnext/accounts/doctype/coupon_code/coupon_code.py
Normal file
25
erpnext/accounts/doctype/coupon_code/coupon_code.py
Normal file
@ -0,0 +1,25 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import (strip)
|
||||
class CouponCode(Document):
|
||||
def autoname(self):
|
||||
self.coupon_name = strip(self.coupon_name)
|
||||
self.name = self.coupon_name
|
||||
|
||||
if not self.coupon_code:
|
||||
if self.coupon_type == "Promotional":
|
||||
self.coupon_code =''.join([i for i in self.coupon_name if not i.isdigit()])[0:8].upper()
|
||||
elif self.coupon_type == "Gift Card":
|
||||
self.coupon_code = frappe.generate_hash()[:10].upper()
|
||||
|
||||
def validate(self):
|
||||
if self.coupon_type == "Gift Card":
|
||||
self.maximum_use = 1
|
||||
if not self.customer:
|
||||
frappe.throw(_("Please select the customer."))
|
23
erpnext/accounts/doctype/coupon_code/test_coupon_code.js
Normal file
23
erpnext/accounts/doctype/coupon_code/test_coupon_code.js
Normal file
@ -0,0 +1,23 @@
|
||||
/* eslint-disable */
|
||||
// rename this file from _test_[name] to test_[name] to activate
|
||||
// and remove above this line
|
||||
|
||||
QUnit.test("test: Coupon Code", function (assert) {
|
||||
let done = assert.async();
|
||||
|
||||
// number of asserts
|
||||
assert.expect(1);
|
||||
|
||||
frappe.run_serially([
|
||||
// insert a new Coupon Code
|
||||
() => frappe.tests.make('Coupon Code', [
|
||||
// values to be set
|
||||
{key: 'value'}
|
||||
]),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.key, 'value');
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
|
||||
});
|
132
erpnext/accounts/doctype/coupon_code/test_coupon_code.py
Normal file
132
erpnext/accounts/doctype/coupon_code/test_coupon_code.py
Normal file
@ -0,0 +1,132 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import unittest
|
||||
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
||||
from erpnext.stock.get_item_details import get_item_details
|
||||
from frappe.test_runner import make_test_objects
|
||||
|
||||
def test_create_test_data():
|
||||
frappe.set_user("Administrator")
|
||||
# create test item
|
||||
if not frappe.db.exists("Item","_Test Tesla Car"):
|
||||
item = frappe.get_doc({
|
||||
"description": "_Test Tesla Car",
|
||||
"doctype": "Item",
|
||||
"has_batch_no": 0,
|
||||
"has_serial_no": 0,
|
||||
"inspection_required": 0,
|
||||
"is_stock_item": 1,
|
||||
"opening_stock":100,
|
||||
"is_sub_contracted_item": 0,
|
||||
"item_code": "_Test Tesla Car",
|
||||
"item_group": "_Test Item Group",
|
||||
"item_name": "_Test Tesla Car",
|
||||
"apply_warehouse_wise_reorder_level": 0,
|
||||
"warehouse":"_Test Warehouse - _TC",
|
||||
"gst_hsn_code": "999800",
|
||||
"valuation_rate": 5000,
|
||||
"standard_rate":5000,
|
||||
"item_defaults": [{
|
||||
"company": "_Test Company",
|
||||
"default_warehouse": "_Test Warehouse - _TC",
|
||||
"default_price_list":"_Test Price List",
|
||||
"expense_account": "_Test Account Cost for Goods Sold - _TC",
|
||||
"buying_cost_center": "_Test Cost Center - _TC",
|
||||
"selling_cost_center": "_Test Cost Center - _TC",
|
||||
"income_account": "Sales - _TC"
|
||||
}],
|
||||
"show_in_website": 1,
|
||||
"route":"-test-tesla-car",
|
||||
"website_warehouse": "_Test Warehouse - _TC"
|
||||
})
|
||||
item.insert()
|
||||
# create test item price
|
||||
item_price = frappe.get_list('Item Price', filters={'item_code': '_Test Tesla Car', 'price_list': '_Test Price List'}, fields=['name'])
|
||||
if len(item_price)==0:
|
||||
item_price = frappe.get_doc({
|
||||
"doctype": "Item Price",
|
||||
"item_code": "_Test Tesla Car",
|
||||
"price_list": "_Test Price List",
|
||||
"price_list_rate": 5000
|
||||
})
|
||||
item_price.insert()
|
||||
# create test item pricing rule
|
||||
if not frappe.db.exists("Pricing Rule","_Test Pricing Rule for _Test Item"):
|
||||
item_pricing_rule = frappe.get_doc({
|
||||
"doctype": "Pricing Rule",
|
||||
"title": "_Test Pricing Rule for _Test Item",
|
||||
"apply_on": "Item Code",
|
||||
"items": [{
|
||||
"item_code": "_Test Tesla Car"
|
||||
}],
|
||||
"warehouse":"_Test Warehouse - _TC",
|
||||
"coupon_code_based":1,
|
||||
"selling": 1,
|
||||
"rate_or_discount": "Discount Percentage",
|
||||
"discount_percentage": 30,
|
||||
"company": "_Test Company",
|
||||
"currency":"INR",
|
||||
"for_price_list":"_Test Price List"
|
||||
})
|
||||
item_pricing_rule.insert()
|
||||
# create test item sales partner
|
||||
if not frappe.db.exists("Sales Partner","_Test Coupon Partner"):
|
||||
sales_partner = frappe.get_doc({
|
||||
"doctype": "Sales Partner",
|
||||
"partner_name":"_Test Coupon Partner",
|
||||
"commission_rate":2,
|
||||
"referral_code": "COPART"
|
||||
})
|
||||
sales_partner.insert()
|
||||
# create test item coupon code
|
||||
if not frappe.db.exists("Coupon Code","SAVE30"):
|
||||
coupon_code = frappe.get_doc({
|
||||
"doctype": "Coupon Code",
|
||||
"coupon_name":"SAVE30",
|
||||
"coupon_code":"SAVE30",
|
||||
"pricing_rule": "_Test Pricing Rule for _Test Item",
|
||||
"valid_from": "2014-01-01",
|
||||
"maximum_use":1,
|
||||
"used":0
|
||||
})
|
||||
coupon_code.insert()
|
||||
|
||||
|
||||
class TestCouponCode(unittest.TestCase):
|
||||
def setUp(self):
|
||||
test_create_test_data()
|
||||
|
||||
def tearDown(self):
|
||||
frappe.set_user("Administrator")
|
||||
|
||||
def test_1_check_coupon_code_used_before_so(self):
|
||||
coupon_code = frappe.get_doc("Coupon Code", frappe.db.get_value("Coupon Code", {"coupon_name":"SAVE30"}))
|
||||
# reset used coupon code count
|
||||
coupon_code.used=0
|
||||
coupon_code.save()
|
||||
# check no coupon code is used before sales order is made
|
||||
self.assertEqual(coupon_code.get("used"),0)
|
||||
|
||||
def test_2_sales_order_with_coupon_code(self):
|
||||
so = make_sales_order(customer="_Test Customer",selling_price_list="_Test Price List",item_code="_Test Tesla Car", rate=5000,qty=1, do_not_submit=True)
|
||||
so = frappe.get_doc('Sales Order', so.name)
|
||||
# check item price before coupon code is applied
|
||||
self.assertEqual(so.items[0].rate, 5000)
|
||||
so.coupon_code='SAVE30'
|
||||
so.sales_partner='_Test Coupon Partner'
|
||||
so.save()
|
||||
# check item price after coupon code is applied
|
||||
self.assertEqual(so.items[0].rate, 3500)
|
||||
so.submit()
|
||||
|
||||
def test_3_check_coupon_code_used_after_so(self):
|
||||
doc = frappe.get_doc("Coupon Code", frappe.db.get_value("Coupon Code", {"coupon_name":"SAVE30"}))
|
||||
# check no coupon code is used before sales order is made
|
||||
self.assertEqual(doc.get("used"),1)
|
||||
|
||||
|
||||
|
@ -608,15 +608,9 @@ $.extend(erpnext.journal_entry, {
|
||||
},
|
||||
|
||||
account_query: function(frm) {
|
||||
var inter_company = 0;
|
||||
if (frm.doc.voucher_type == "Inter Company Journal Entry") {
|
||||
inter_company = 1;
|
||||
}
|
||||
|
||||
var filters = {
|
||||
company: frm.doc.company,
|
||||
is_group: 0,
|
||||
inter_company_account: inter_company
|
||||
is_group: 0
|
||||
};
|
||||
if(!frm.doc.multi_currency) {
|
||||
$.extend(filters, {
|
||||
|
@ -40,7 +40,7 @@
|
||||
"fields": [
|
||||
{
|
||||
"bold": 1,
|
||||
"columns": 3,
|
||||
"columns": 2,
|
||||
"fieldname": "account",
|
||||
"fieldtype": "Link",
|
||||
"in_global_search": 1,
|
||||
@ -90,14 +90,16 @@
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"default": "Customer",
|
||||
"fieldname": "party_type",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Party Type",
|
||||
"options": "DocType",
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"columns": 3,
|
||||
"columns": 2,
|
||||
"fieldname": "party",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"in_list_view": 1,
|
||||
@ -270,7 +272,7 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2019-09-12 12:16:17.588399",
|
||||
"modified": "2019-10-02 12:23:21.693443",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Journal Entry Account",
|
||||
|
@ -940,6 +940,10 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
|
||||
bank = get_default_bank_cash_account(doc.company, "Bank", mode_of_payment=doc.get("mode_of_payment"),
|
||||
account=bank_account)
|
||||
|
||||
if not bank:
|
||||
bank = get_default_bank_cash_account(doc.company, "Cash", mode_of_payment=doc.get("mode_of_payment"),
|
||||
account=bank_account)
|
||||
|
||||
paid_amount = received_amount = 0
|
||||
if party_account_currency == bank.account_currency:
|
||||
paid_amount = received_amount = abs(outstanding_amount)
|
||||
@ -1041,7 +1045,7 @@ def make_payment_order(source_name, target_doc=None):
|
||||
|
||||
def update_item(source_doc, target_doc, source_parent):
|
||||
target_doc.bank_account = source_parent.party_bank_account
|
||||
target_doc.amount = source_parent.base_paid_amount
|
||||
target_doc.amount = source_doc.allocated_amount
|
||||
target_doc.account = source_parent.paid_to
|
||||
target_doc.payment_entry = source_parent.name
|
||||
target_doc.supplier = source_parent.party
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -249,6 +249,9 @@ def get_pricing_rule_for_item(args, price_list_rate=0, doc=None):
|
||||
if pricing_rule.mixed_conditions or pricing_rule.apply_rule_on_other:
|
||||
continue
|
||||
|
||||
if pricing_rule.coupon_code_based==1 and args.coupon_code==None:
|
||||
return item_details
|
||||
|
||||
if (not pricing_rule.validate_applied_rule and
|
||||
pricing_rule.price_or_product_discount == "Price"):
|
||||
apply_price_discount_pricing_rule(pricing_rule, item_details, args)
|
||||
|
@ -531,4 +531,32 @@ def validate_pricing_rule_for_different_cond(doc):
|
||||
for d in doc.get("items"):
|
||||
validate_pricing_rule_on_items(doc, d, True)
|
||||
|
||||
return doc
|
||||
return doc
|
||||
|
||||
def validate_coupon_code(coupon_name):
|
||||
from frappe.utils import today,getdate
|
||||
coupon=frappe.get_doc("Coupon Code",coupon_name)
|
||||
if coupon.valid_from:
|
||||
if coupon.valid_from > getdate(today()) :
|
||||
frappe.throw(_("Sorry,coupon code validity has not started"))
|
||||
elif coupon.valid_upto:
|
||||
if coupon.valid_upto < getdate(today()) :
|
||||
frappe.throw(_("Sorry,coupon code validity has expired"))
|
||||
elif coupon.used>=coupon.maximum_use:
|
||||
frappe.throw(_("Sorry,coupon code are exhausted"))
|
||||
else:
|
||||
return
|
||||
|
||||
def update_coupon_code_count(coupon_name,transaction_type):
|
||||
coupon=frappe.get_doc("Coupon Code",coupon_name)
|
||||
if coupon:
|
||||
if transaction_type=='used':
|
||||
if coupon.used<coupon.maximum_use:
|
||||
coupon.used=coupon.used+1
|
||||
coupon.save(ignore_permissions=True)
|
||||
else:
|
||||
frappe.throw(_("{0} Coupon used are {1}. Allowed quantity is exhausted").format(coupon.coupon_code,coupon.used))
|
||||
elif transaction_type=='cancelled':
|
||||
if coupon.used>0:
|
||||
coupon.used=coupon.used-1
|
||||
coupon.save(ignore_permissions=True)
|
@ -880,6 +880,17 @@ class PurchaseInvoice(BuyingController):
|
||||
# calculate totals again after applying TDS
|
||||
self.calculate_taxes_and_totals()
|
||||
|
||||
def get_list_context(context=None):
|
||||
from erpnext.controllers.website_list_for_contact import get_list_context
|
||||
list_context = get_list_context(context)
|
||||
list_context.update({
|
||||
'show_sidebar': True,
|
||||
'show_search': True,
|
||||
'no_breadcrumbs': True,
|
||||
'title': _('Purchase Invoices'),
|
||||
})
|
||||
return list_context
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_debit_note(source_name, target_doc=None):
|
||||
from erpnext.controllers.sales_and_purchase_return import make_return_doc
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -16,7 +16,7 @@ frappe.ui.form.on('Share Transfer', {
|
||||
};
|
||||
};
|
||||
});
|
||||
if (frm.doc.docstatus == 1) {
|
||||
if (frm.doc.docstatus == 1 && frm.doc.equity_or_liability_account && frm.doc.asset_account) {
|
||||
frm.add_custom_button(__('Create Journal Entry'), function () {
|
||||
erpnext.share_transfer.make_jv(frm);
|
||||
});
|
||||
|
@ -12,7 +12,7 @@ from frappe.utils import (add_days, getdate, formatdate, date_diff,
|
||||
from frappe.contacts.doctype.address.address import (get_address_display,
|
||||
get_default_address, get_company_address)
|
||||
from frappe.contacts.doctype.contact.contact import get_contact_details, get_default_contact
|
||||
from erpnext.exceptions import PartyFrozen, InvalidAccountCurrency
|
||||
from erpnext.exceptions import PartyFrozen, PartyDisabled, InvalidAccountCurrency
|
||||
from erpnext.accounts.utils import get_fiscal_year
|
||||
from erpnext import get_company_currency
|
||||
|
||||
@ -446,7 +446,9 @@ def validate_party_frozen_disabled(party_type, party_name):
|
||||
if party_type and party_name:
|
||||
if party_type in ("Customer", "Supplier"):
|
||||
party = frappe.get_cached_value(party_type, party_name, ["is_frozen", "disabled"], as_dict=True)
|
||||
if party.get("is_frozen"):
|
||||
if party.disabled:
|
||||
frappe.throw(_("{0} {1} is disabled").format(party_type, party_name), PartyDisabled)
|
||||
elif party.get("is_frozen"):
|
||||
frozen_accounts_modifier = frappe.db.get_single_value( 'Accounts Settings', 'frozen_accounts_modifier')
|
||||
if not frozen_accounts_modifier in frappe.get_roles():
|
||||
frappe.throw(_("{0} {1} is frozen").format(party_type, party_name), PartyFrozen)
|
||||
|
@ -9,7 +9,7 @@
|
||||
</div>
|
||||
<div class="col-xs-{{ "3" if df.fieldtype=="Check" else "7" }} value">
|
||||
{% if doc.get(df.fieldname) != None -%}
|
||||
{{ frappe.utils.fmt_money((doc[df.fieldname])|int|abs, currency=doc.currency) }}
|
||||
{{ frappe.utils.fmt_money((doc[df.fieldname])|abs, currency=doc.currency) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
@ -26,7 +26,7 @@
|
||||
<div class="col-xs-5 {%- if doc.align_labels_right %} text-right{%- endif -%}">
|
||||
<label>{{ charge.get_formatted("description") }}</label></div>
|
||||
<div class="col-xs-7 text-right">
|
||||
{{ frappe.utils.fmt_money((charge.tax_amount)|int|abs, currency=doc.currency) }}
|
||||
{{ frappe.utils.fmt_money((charge.tax_amount)|abs, currency=doc.currency) }}
|
||||
</div>
|
||||
</div>
|
||||
{%- endif -%}
|
||||
@ -65,8 +65,10 @@
|
||||
{% for tdf in visible_columns %}
|
||||
{% if not d.flags.compact_item_print or tdf.fieldname in doc.get(df.fieldname)[0].flags.compact_item_fields %}
|
||||
<td class="{{ get_align_class(tdf) }}" {{ fieldmeta(df) }}>
|
||||
{% if tdf.fieldtype == 'Currency' %}
|
||||
<div class="value">{{ frappe.utils.fmt_money((d[tdf.fieldname])|int|abs, currency=doc.currency) }}</div></td>
|
||||
{% if tdf.fieldname == 'qty' %}
|
||||
<div class="value">{{ (d[tdf.fieldname])|abs }}</div></td>
|
||||
{% elif tdf.fieldtype == 'Currency' %}
|
||||
<div class="value">{{ frappe.utils.fmt_money((d[tdf.fieldname])|abs, currency=doc.currency) }}</div></td>
|
||||
{% else %}
|
||||
<div class="value">{{ print_value(tdf, d, doc, visible_columns) }}</div></td>
|
||||
{% endif %}
|
||||
@ -117,7 +119,7 @@
|
||||
{{ render_currency(df, doc) }}
|
||||
{% elif df.fieldtype =='Table' %}
|
||||
{{ render_table(df, doc)}}
|
||||
{% elif doc[df.fieldname] %}
|
||||
{% elif doc[df.fieldname] and df.fieldname != 'total_qty' %}
|
||||
{{ render_field(df, doc) }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
@ -20,12 +20,7 @@ class Asset(AccountsController):
|
||||
self.validate_asset_values()
|
||||
self.validate_item()
|
||||
self.set_missing_values()
|
||||
if self.calculate_depreciation:
|
||||
self.set_depreciation_rate()
|
||||
self.make_depreciation_schedule()
|
||||
self.set_accumulated_depreciation()
|
||||
else:
|
||||
self.finance_books = []
|
||||
self.prepare_depreciation_data()
|
||||
if self.get("schedules"):
|
||||
self.validate_expected_value_after_useful_life()
|
||||
|
||||
@ -45,6 +40,17 @@ class Asset(AccountsController):
|
||||
delete_gl_entries(voucher_type='Asset', voucher_no=self.name)
|
||||
self.db_set('booked_fixed_asset', 0)
|
||||
|
||||
def prepare_depreciation_data(self):
|
||||
if self.calculate_depreciation:
|
||||
self.value_after_depreciation = 0
|
||||
self.set_depreciation_rate()
|
||||
self.make_depreciation_schedule()
|
||||
self.set_accumulated_depreciation()
|
||||
else:
|
||||
self.finance_books = []
|
||||
self.value_after_depreciation = (flt(self.gross_purchase_amount) -
|
||||
flt(self.opening_accumulated_depreciation))
|
||||
|
||||
def validate_item(self):
|
||||
item = frappe.get_cached_value("Item", self.item_code,
|
||||
["is_fixed_asset", "is_stock_item", "disabled"], as_dict=1)
|
||||
|
@ -188,7 +188,8 @@ def get_gl_entries_on_asset_disposal(asset, selling_amount=0, finance_book=None)
|
||||
idx = d.idx
|
||||
break
|
||||
|
||||
value_after_depreciation = asset.finance_books[idx - 1].value_after_depreciation
|
||||
value_after_depreciation = (asset.finance_books[idx - 1].value_after_depreciation
|
||||
if asset.calculate_depreciation else asset.value_after_depreciation)
|
||||
accumulated_depr_amount = flt(asset.gross_purchase_amount) - flt(value_after_depreciation)
|
||||
|
||||
gl_entries = [
|
||||
|
@ -16,8 +16,8 @@ frappe.query_reports["Fixed Asset Register"] = {
|
||||
fieldname:"status",
|
||||
label: __("Status"),
|
||||
fieldtype: "Select",
|
||||
options: "In Store\nDisposed",
|
||||
default: 'In Store',
|
||||
options: "In Location\nDisposed",
|
||||
default: 'In Location',
|
||||
reqd: 1
|
||||
},
|
||||
{
|
||||
|
@ -1,13 +1,13 @@
|
||||
{
|
||||
"add_total_row": 0,
|
||||
"creation": "2019-09-23 16:35:02.836134",
|
||||
"disable_prepared_report": 0,
|
||||
"disable_prepared_report": 1,
|
||||
"disabled": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Report",
|
||||
"idx": 0,
|
||||
"is_standard": "Yes",
|
||||
"modified": "2019-09-23 16:35:02.836134",
|
||||
"modified": "2019-10-22 13:00:31.539726",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Assets",
|
||||
"name": "Fixed Asset Register",
|
||||
|
@ -4,6 +4,7 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.utils import cstr
|
||||
|
||||
def execute(filters=None):
|
||||
filters = frappe._dict(filters or {})
|
||||
@ -101,7 +102,7 @@ def get_conditions(filters):
|
||||
|
||||
# In Store assets are those that are not sold or scrapped
|
||||
operand = 'not in'
|
||||
if status not in 'In Store':
|
||||
if status not in 'In Location':
|
||||
operand = 'in'
|
||||
|
||||
conditions['status'] = (operand, ['Sold', 'Scrapped'])
|
||||
@ -149,12 +150,12 @@ def get_finance_book_value_map(finance_book=''):
|
||||
FROM `tabAsset Finance Book`
|
||||
WHERE
|
||||
parentfield='finance_books'
|
||||
AND finance_book=%s''', (finance_book)))
|
||||
AND ifnull(finance_book, '')=%s''', cstr(finance_book)))
|
||||
|
||||
def get_purchase_receipt_supplier_map():
|
||||
return frappe._dict(frappe.db.sql(''' Select
|
||||
pr.name, pr.supplier
|
||||
FROM `tabPurchase Receipt` pr, `tabPurchase Receipt Item` pri
|
||||
FROM `tabPurchase Receipt` pr, `tabPurchase Receipt Item` pri
|
||||
WHERE
|
||||
pri.parent = pr.name
|
||||
AND pri.is_fixed_asset=1
|
||||
@ -164,7 +165,7 @@ def get_purchase_receipt_supplier_map():
|
||||
def get_purchase_invoice_supplier_map():
|
||||
return frappe._dict(frappe.db.sql(''' Select
|
||||
pi.name, pi.supplier
|
||||
FROM `tabPurchase Invoice` pi, `tabPurchase Invoice Item` pii
|
||||
FROM `tabPurchase Invoice` pi, `tabPurchase Invoice Item` pii
|
||||
WHERE
|
||||
pii.parent = pi.name
|
||||
AND pii.is_fixed_asset=1
|
||||
|
@ -386,7 +386,21 @@ def make_purchase_receipt(source_name, target_doc=None):
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_purchase_invoice(source_name, target_doc=None):
|
||||
return get_mapped_purchase_invoice(source_name, target_doc)
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_purchase_invoice_from_portal(purchase_order_name):
|
||||
doc = get_mapped_purchase_invoice(purchase_order_name, ignore_permissions=True)
|
||||
if doc.contact_email != frappe.session.user:
|
||||
frappe.throw(_('Not Permitted'), frappe.PermissionError)
|
||||
doc.save()
|
||||
frappe.db.commit()
|
||||
frappe.response['type'] = 'redirect'
|
||||
frappe.response.location = '/purchase-invoices/' + doc.name
|
||||
|
||||
def get_mapped_purchase_invoice(source_name, target_doc=None, ignore_permissions=False):
|
||||
def postprocess(source, target):
|
||||
target.flags.ignore_permissions = ignore_permissions
|
||||
set_missing_values(source, target)
|
||||
#Get the advance paid Journal Entries in Purchase Invoice Advance
|
||||
|
||||
@ -437,7 +451,8 @@ def make_purchase_invoice(source_name, target_doc=None):
|
||||
"add_if_empty": True
|
||||
}
|
||||
|
||||
doc = get_mapped_doc("Purchase Order", source_name, fields, target_doc, postprocess)
|
||||
doc = get_mapped_doc("Purchase Order", source_name, fields,
|
||||
target_doc, postprocess, ignore_permissions=ignore_permissions)
|
||||
|
||||
return doc
|
||||
|
||||
@ -501,6 +516,17 @@ def get_item_details(items):
|
||||
|
||||
return item_details
|
||||
|
||||
def get_list_context(context=None):
|
||||
from erpnext.controllers.website_list_for_contact import get_list_context
|
||||
list_context = get_list_context(context)
|
||||
list_context.update({
|
||||
'show_sidebar': True,
|
||||
'show_search': True,
|
||||
'no_breadcrumbs': True,
|
||||
'title': _('Purchase Orders'),
|
||||
})
|
||||
return list_context
|
||||
|
||||
@frappe.whitelist()
|
||||
def update_status(status, name):
|
||||
po = frappe.get_doc("Purchase Order", name)
|
||||
|
@ -589,6 +589,23 @@ class TestPurchaseOrder(unittest.TestCase):
|
||||
frappe.db.set_value("Accounts Settings", "Accounts Settings",
|
||||
"unlink_advance_payment_on_cancelation_of_order", 0)
|
||||
|
||||
def test_schedule_date(self):
|
||||
po = create_purchase_order(do_not_submit=True)
|
||||
po.schedule_date = None
|
||||
po.append("items", {
|
||||
"item_code": "_Test Item",
|
||||
"qty": 1,
|
||||
"rate": 100,
|
||||
"schedule_date": add_days(nowdate(), 5)
|
||||
})
|
||||
po.save()
|
||||
self.assertEqual(po.schedule_date, add_days(nowdate(), 1))
|
||||
|
||||
po.items[0].schedule_date = add_days(nowdate(), 2)
|
||||
po.save()
|
||||
self.assertEqual(po.schedule_date, add_days(nowdate(), 2))
|
||||
|
||||
|
||||
def make_pr_against_po(po, received_qty=0):
|
||||
pr = make_purchase_receipt(po)
|
||||
pr.get("items")[0].qty = received_qty or 5
|
||||
|
@ -5,6 +5,7 @@ from __future__ import unicode_literals
|
||||
|
||||
import frappe, unittest
|
||||
from erpnext.accounts.party import get_due_date
|
||||
from erpnext.exceptions import PartyDisabled
|
||||
from frappe.test_runner import make_test_records
|
||||
|
||||
test_dependencies = ['Payment Term', 'Payment Terms Template']
|
||||
@ -70,7 +71,7 @@ class TestSupplier(unittest.TestCase):
|
||||
|
||||
po = create_purchase_order(do_not_save=True)
|
||||
|
||||
self.assertRaises(frappe.ValidationError, po.save)
|
||||
self.assertRaises(PartyDisabled, po.save)
|
||||
|
||||
frappe.db.set_value("Supplier", "_Test Supplier", "disabled", 0)
|
||||
|
||||
|
@ -18,7 +18,7 @@ def get_data():
|
||||
"onboard_present": 1
|
||||
},
|
||||
{
|
||||
"module_name": "Accounting",
|
||||
"module_name": "Accounts",
|
||||
"category": "Modules",
|
||||
"label": _("Accounting"),
|
||||
"color": "#3498db",
|
||||
|
@ -127,7 +127,11 @@ def get_data():
|
||||
"name": "Shipping Rule",
|
||||
"description": _("Rules for adding shipping costs."),
|
||||
},
|
||||
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Coupon Code",
|
||||
"description": _("Define coupon codes."),
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -606,8 +606,13 @@ class AccountsController(TransactionBase):
|
||||
|
||||
max_allowed_amt = flt(ref_amt * (100 + allowance) / 100)
|
||||
|
||||
if total_billed_amt < 0 and max_allowed_amt < 0:
|
||||
# while making debit note against purchase return entry(purchase receipt) getting overbill error
|
||||
total_billed_amt = abs(total_billed_amt)
|
||||
max_allowed_amt = abs(max_allowed_amt)
|
||||
|
||||
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 Stock Settings")
|
||||
frappe.throw(_("Cannot overbill for Item {0} in row {1} more than {2}. To allow over-billing, please set allowance in Accounts Settings")
|
||||
.format(item.item_code, item.idx, max_allowed_amt))
|
||||
|
||||
def get_company_default(self, fieldname):
|
||||
@ -1195,10 +1200,22 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
|
||||
child_item.rate = flt(d.get("rate"))
|
||||
|
||||
if flt(child_item.price_list_rate):
|
||||
discount = flt((1 - flt(child_item.rate) / flt(child_item.price_list_rate)) * 100.0,
|
||||
child_item.precision("discount_percentage"))
|
||||
if discount > 0:
|
||||
child_item.discount_percentage = discount
|
||||
if flt(child_item.rate) > flt(child_item.price_list_rate):
|
||||
# if rate is greater than price_list_rate, set margin
|
||||
# or set discount
|
||||
child_item.discount_percentage = 0
|
||||
child_item.margin_type = "Amount"
|
||||
child_item.margin_rate_or_amount = flt(child_item.rate - child_item.price_list_rate,
|
||||
child_item.precision("margin_rate_or_amount"))
|
||||
child_item.rate_with_margin = child_item.rate
|
||||
else:
|
||||
child_item.discount_percentage = flt((1 - flt(child_item.rate) / flt(child_item.price_list_rate)) * 100.0,
|
||||
child_item.precision("discount_percentage"))
|
||||
child_item.discount_amount = flt(
|
||||
child_item.price_list_rate) - flt(child_item.rate)
|
||||
child_item.margin_type = ""
|
||||
child_item.margin_rate_or_amount = 0
|
||||
child_item.rate_with_margin = 0
|
||||
|
||||
child_item.flags.ignore_validate_update_after_submit = True
|
||||
if new_child_flag:
|
||||
@ -1211,6 +1228,8 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
|
||||
parent.flags.ignore_validate_update_after_submit = True
|
||||
parent.set_qty_as_per_stock_uom()
|
||||
parent.calculate_taxes_and_totals()
|
||||
if parent_doctype == "Sales Order":
|
||||
parent.set_gross_profit()
|
||||
frappe.get_doc('Authorization Control').validate_approving_authority(parent.doctype,
|
||||
parent.company, parent.base_grand_total)
|
||||
|
||||
|
@ -695,8 +695,10 @@ class BuyingController(StockController):
|
||||
def validate_schedule_date(self):
|
||||
if not self.get("items"):
|
||||
return
|
||||
if not self.schedule_date:
|
||||
self.schedule_date = min([d.schedule_date for d in self.get("items")])
|
||||
|
||||
earliest_schedule_date = min([d.schedule_date for d in self.get("items")])
|
||||
if earliest_schedule_date:
|
||||
self.schedule_date = earliest_schedule_date
|
||||
|
||||
if self.schedule_date:
|
||||
for d in self.get('items'):
|
||||
|
@ -280,22 +280,31 @@ def get_batch_no(doctype, txt, searchfield, start, page_len, filters):
|
||||
"page_len": page_len
|
||||
}
|
||||
|
||||
having_clause = "having sum(sle.actual_qty) > 0"
|
||||
if filters.get("is_return"):
|
||||
having_clause = ""
|
||||
|
||||
if args.get('warehouse'):
|
||||
batch_nos = frappe.db.sql("""select sle.batch_no, round(sum(sle.actual_qty),2), sle.stock_uom, concat('MFG-',batch.manufacturing_date), concat('EXP-',batch.expiry_date)
|
||||
from `tabStock Ledger Entry` sle
|
||||
INNER JOIN `tabBatch` batch on sle.batch_no = batch.name
|
||||
where
|
||||
batch.disabled = 0
|
||||
and sle.item_code = %(item_code)s
|
||||
and sle.warehouse = %(warehouse)s
|
||||
and (sle.batch_no like %(txt)s
|
||||
or batch.manufacturing_date like %(txt)s)
|
||||
and batch.docstatus < 2
|
||||
{0}
|
||||
{match_conditions}
|
||||
group by batch_no having sum(sle.actual_qty) > 0
|
||||
order by batch.expiry_date, sle.batch_no desc
|
||||
limit %(start)s, %(page_len)s""".format(cond, match_conditions=get_match_cond(doctype)), args)
|
||||
batch_nos = frappe.db.sql("""select sle.batch_no, round(sum(sle.actual_qty),2), sle.stock_uom,
|
||||
concat('MFG-',batch.manufacturing_date), concat('EXP-',batch.expiry_date)
|
||||
from `tabStock Ledger Entry` sle
|
||||
INNER JOIN `tabBatch` batch on sle.batch_no = batch.name
|
||||
where
|
||||
batch.disabled = 0
|
||||
and sle.item_code = %(item_code)s
|
||||
and sle.warehouse = %(warehouse)s
|
||||
and (sle.batch_no like %(txt)s
|
||||
or batch.manufacturing_date like %(txt)s)
|
||||
and batch.docstatus < 2
|
||||
{cond}
|
||||
{match_conditions}
|
||||
group by batch_no {having_clause}
|
||||
order by batch.expiry_date, sle.batch_no desc
|
||||
limit %(start)s, %(page_len)s""".format(
|
||||
cond=cond,
|
||||
match_conditions=get_match_cond(doctype),
|
||||
having_clause = having_clause
|
||||
), args)
|
||||
|
||||
return batch_nos
|
||||
else:
|
||||
|
@ -37,9 +37,9 @@ status_map = {
|
||||
"Sales Order": [
|
||||
["Draft", None],
|
||||
["To Deliver and Bill", "eval:self.per_delivered < 100 and self.per_billed < 100 and self.docstatus == 1"],
|
||||
["To Bill", "eval:self.per_delivered == 100 and self.per_billed < 100 and self.docstatus == 1"],
|
||||
["To Deliver", "eval:self.per_delivered < 100 and self.per_billed == 100 and self.docstatus == 1"],
|
||||
["Completed", "eval:self.per_delivered == 100 and self.per_billed == 100 and self.docstatus == 1"],
|
||||
["To Bill", "eval:(self.per_delivered == 100 or self.skip_delivery_note) and self.per_billed < 100 and self.docstatus == 1"],
|
||||
["To Deliver", "eval:self.per_delivered < 100 and self.per_billed == 100 and self.docstatus == 1 and not self.skip_delivery_note"],
|
||||
["Completed", "eval:(self.per_delivered == 100 or self.skip_delivery_note) and self.per_billed == 100 and self.docstatus == 1"],
|
||||
["Cancelled", "eval:self.docstatus==2"],
|
||||
["Closed", "eval:self.status=='Closed'"],
|
||||
["On Hold", "eval:self.status=='On Hold'"],
|
||||
|
@ -140,6 +140,8 @@ def period_wise_columns_query(filters, trans):
|
||||
|
||||
if trans in ['Purchase Receipt', 'Delivery Note', 'Purchase Invoice', 'Sales Invoice']:
|
||||
trans_date = 'posting_date'
|
||||
if filters.period_based_on:
|
||||
trans_date = filters.period_based_on
|
||||
else:
|
||||
trans_date = 'transaction_date'
|
||||
|
||||
|
@ -25,7 +25,7 @@ def get_transaction_list(doctype, txt=None, filters=None, limit_start=0, limit_p
|
||||
|
||||
if not filters: filters = []
|
||||
|
||||
if doctype == 'Supplier Quotation':
|
||||
if doctype in ['Supplier Quotation', 'Purchase Invoice']:
|
||||
filters.append((doctype, 'docstatus', '<', 2))
|
||||
else:
|
||||
filters.append((doctype, 'docstatus', '=', 1))
|
||||
@ -175,4 +175,4 @@ def get_customer_field_name(doctype):
|
||||
if doctype == 'Quotation':
|
||||
return 'party_name'
|
||||
else:
|
||||
return 'customer'
|
||||
return 'customer'
|
||||
|
@ -146,14 +146,7 @@ def _make_customer(source_name, target_doc=None, ignore_permissions=False):
|
||||
@frappe.whitelist()
|
||||
def make_opportunity(source_name, target_doc=None):
|
||||
def set_missing_values(source, target):
|
||||
address = frappe.get_all('Dynamic Link', {
|
||||
'link_doctype': source.doctype,
|
||||
'link_name': source.name,
|
||||
'parenttype': 'Address',
|
||||
}, ['parent'], limit=1)
|
||||
|
||||
if address:
|
||||
target.customer_address = address[0].parent
|
||||
_set_missing_values(source, target)
|
||||
|
||||
target_doc = get_mapped_doc("Lead", source_name,
|
||||
{"Lead": {
|
||||
@ -173,13 +166,17 @@ def make_opportunity(source_name, target_doc=None):
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_quotation(source_name, target_doc=None):
|
||||
def set_missing_values(source, target):
|
||||
_set_missing_values(source, target)
|
||||
|
||||
target_doc = get_mapped_doc("Lead", source_name,
|
||||
{"Lead": {
|
||||
"doctype": "Quotation",
|
||||
"field_map": {
|
||||
"name": "party_name"
|
||||
}
|
||||
}}, target_doc)
|
||||
}}, target_doc, set_missing_values)
|
||||
|
||||
target_doc.quotation_to = "Lead"
|
||||
target_doc.run_method("set_missing_values")
|
||||
target_doc.run_method("set_other_charges")
|
||||
@ -187,6 +184,25 @@ def make_quotation(source_name, target_doc=None):
|
||||
|
||||
return target_doc
|
||||
|
||||
def _set_missing_values(source, target):
|
||||
address = frappe.get_all('Dynamic Link', {
|
||||
'link_doctype': source.doctype,
|
||||
'link_name': source.name,
|
||||
'parenttype': 'Address',
|
||||
}, ['parent'], limit=1)
|
||||
|
||||
contact = frappe.get_all('Dynamic Link', {
|
||||
'link_doctype': source.doctype,
|
||||
'link_name': source.name,
|
||||
'parenttype': 'Contact',
|
||||
}, ['parent'], limit=1)
|
||||
|
||||
if address:
|
||||
target.customer_address = address[0].parent
|
||||
|
||||
if contact:
|
||||
target.contact_person = contact[0].parent
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_lead_details(lead, posting_date=None, company=None):
|
||||
if not lead: return {}
|
||||
|
@ -167,7 +167,7 @@ erpnext.crm.Opportunity = frappe.ui.form.Controller.extend({
|
||||
if (me.frm.doc.opportunity_from == "Lead") {
|
||||
me.frm.set_query('party_name', erpnext.queries['lead']);
|
||||
}
|
||||
else if (me.frm.doc.opportunity_from == "Cuatomer") {
|
||||
else if (me.frm.doc.opportunity_from == "Customer") {
|
||||
me.frm.set_query('party_name', erpnext.queries['customer']);
|
||||
}
|
||||
},
|
||||
|
@ -17,7 +17,7 @@ def get_last_interaction(contact=None, lead=None):
|
||||
if link.link_doctype == 'Customer':
|
||||
last_issue = get_last_issue_from_customer(link.link_name)
|
||||
query_condition += "(`reference_doctype`=%s AND `reference_name`=%s) OR"
|
||||
values += [link_link_doctype, link_link_name]
|
||||
values += [link.link_doctype, link.link_name]
|
||||
|
||||
if query_condition:
|
||||
# remove extra appended 'OR'
|
||||
|
@ -67,7 +67,7 @@ def get_communication_details(filters):
|
||||
communication_count = None
|
||||
communication_list = []
|
||||
opportunities = frappe.db.get_values('Opportunity', {'opportunity_from': 'Lead'},\
|
||||
['name', 'customer_name', 'lead', 'contact_email'], as_dict=1)
|
||||
['name', 'customer_name', 'contact_email'], as_dict=1)
|
||||
|
||||
for d in opportunities:
|
||||
invoice = frappe.db.sql('''
|
||||
|
@ -10,13 +10,14 @@ from erpnext.demo.domains import data
|
||||
from frappe import _
|
||||
|
||||
def setup(domain):
|
||||
frappe.flags.in_demo = 1
|
||||
complete_setup(domain)
|
||||
setup_demo_page()
|
||||
setup_fiscal_year()
|
||||
setup_holiday_list()
|
||||
setup_user()
|
||||
setup_employee()
|
||||
setup_user_roles()
|
||||
setup_user_roles(domain)
|
||||
setup_role_permissions()
|
||||
setup_custom_field_for_domain()
|
||||
|
||||
@ -183,13 +184,19 @@ def setup_salary_structure(employees, salary_slip_based_on_timesheet=0):
|
||||
|
||||
return ss
|
||||
|
||||
def setup_user_roles():
|
||||
def setup_user_roles(domain):
|
||||
user = frappe.get_doc('User', 'demo@erpnext.com')
|
||||
user.add_roles('HR User', 'HR Manager', 'Accounts User', 'Accounts Manager',
|
||||
'Stock User', 'Stock Manager', 'Sales User', 'Sales Manager', 'Purchase User',
|
||||
'Purchase Manager', 'Projects User', 'Manufacturing User', 'Manufacturing Manager',
|
||||
'Support Team', 'Academics User', 'Physician', 'Healthcare Administrator', 'Laboratory User',
|
||||
'Nursing User', 'Patient')
|
||||
'Support Team')
|
||||
|
||||
if domain == "Healthcare":
|
||||
user.add_roles('Physician', 'Healthcare Administrator', 'Laboratory User',
|
||||
'Nursing User', 'Patient')
|
||||
|
||||
if domain == "Education":
|
||||
user.add_roles('Academics User')
|
||||
|
||||
if not frappe.db.get_global('demo_hr_user'):
|
||||
user = frappe.get_doc('User', 'CaitlinSnow@example.com')
|
||||
@ -219,7 +226,7 @@ def setup_user_roles():
|
||||
|
||||
if not frappe.db.get_global('demo_manufacturing_user'):
|
||||
user = frappe.get_doc('User', 'NeptuniaAquaria@example.com')
|
||||
user.add_roles('Manufacturing User', 'Stock User', 'Purchase User', 'Accounts User')
|
||||
user.add_roles('Manufacturing User', 'Stock Manager', 'Stock User', 'Purchase User', 'Accounts User')
|
||||
update_employee_department(user.name, 'Production')
|
||||
frappe.db.set_global('demo_manufacturing_user', user.name)
|
||||
|
||||
@ -241,11 +248,12 @@ def setup_user_roles():
|
||||
update_employee_department(user.name, 'Management')
|
||||
frappe.db.set_global('demo_projects_user', user.name)
|
||||
|
||||
if not frappe.db.get_global('demo_education_user'):
|
||||
user = frappe.get_doc('User', 'ArthurCurry@example.com')
|
||||
user.add_roles('Academics User')
|
||||
update_employee_department(user.name, 'Management')
|
||||
frappe.db.set_global('demo_education_user', user.name)
|
||||
if domain == "Education":
|
||||
if not frappe.db.get_global('demo_education_user'):
|
||||
user = frappe.get_doc('User', 'ArthurCurry@example.com')
|
||||
user.add_roles('Academics User')
|
||||
update_employee_department(user.name, 'Management')
|
||||
frappe.db.set_global('demo_education_user', user.name)
|
||||
|
||||
#Add Expense Approver
|
||||
user = frappe.get_doc('User', 'ClarkKent@example.com')
|
||||
|
@ -73,14 +73,16 @@ def work():
|
||||
make_pos_invoice()
|
||||
|
||||
def make_payment_entries(ref_doctype, report):
|
||||
outstanding_invoices = list(set([r[3] for r in query_report.run(report, {
|
||||
"report_date": frappe.flags.current_date,
|
||||
"company": erpnext.get_default_company()
|
||||
})["result"] if r[2]==ref_doctype]))
|
||||
|
||||
outstanding_invoices = frappe.get_all(ref_doctype, fields=["name"],
|
||||
filters={
|
||||
"company": erpnext.get_default_company(),
|
||||
"outstanding_amount": (">", 0.0)
|
||||
})
|
||||
|
||||
# make Payment Entry
|
||||
for inv in outstanding_invoices[:random.randint(1, 2)]:
|
||||
pe = get_payment_entry(ref_doctype, inv)
|
||||
pe = get_payment_entry(ref_doctype, inv.name)
|
||||
pe.posting_date = frappe.flags.current_date
|
||||
pe.reference_no = random_string(6)
|
||||
pe.reference_date = frappe.flags.current_date
|
||||
@ -91,7 +93,7 @@ def make_payment_entries(ref_doctype, report):
|
||||
|
||||
# make payment via JV
|
||||
for inv in outstanding_invoices[:1]:
|
||||
jv = frappe.get_doc(get_payment_entry_against_invoice(ref_doctype, inv))
|
||||
jv = frappe.get_doc(get_payment_entry_against_invoice(ref_doctype, inv.name))
|
||||
jv.posting_date = frappe.flags.current_date
|
||||
jv.cheque_no = random_string(6)
|
||||
jv.cheque_date = frappe.flags.current_date
|
||||
|
@ -39,61 +39,4 @@ def make_project(current_date):
|
||||
"doctype": "Project",
|
||||
"project_name": "New Product Development " + current_date.strftime("%Y-%m-%d"),
|
||||
})
|
||||
project.set("tasks", [
|
||||
{
|
||||
"title": "Review Requirements",
|
||||
"start_date": frappe.utils.add_days(current_date, 10),
|
||||
"end_date": frappe.utils.add_days(current_date, 11)
|
||||
},
|
||||
{
|
||||
"title": "Design Options",
|
||||
"start_date": frappe.utils.add_days(current_date, 11),
|
||||
"end_date": frappe.utils.add_days(current_date, 20)
|
||||
},
|
||||
{
|
||||
"title": "Make Prototypes",
|
||||
"start_date": frappe.utils.add_days(current_date, 20),
|
||||
"end_date": frappe.utils.add_days(current_date, 30)
|
||||
},
|
||||
{
|
||||
"title": "Customer Feedback on Prototypes",
|
||||
"start_date": frappe.utils.add_days(current_date, 30),
|
||||
"end_date": frappe.utils.add_days(current_date, 40)
|
||||
},
|
||||
{
|
||||
"title": "Freeze Feature Set",
|
||||
"start_date": frappe.utils.add_days(current_date, 40),
|
||||
"end_date": frappe.utils.add_days(current_date, 45)
|
||||
},
|
||||
{
|
||||
"title": "Testing",
|
||||
"start_date": frappe.utils.add_days(current_date, 45),
|
||||
"end_date": frappe.utils.add_days(current_date, 60)
|
||||
},
|
||||
{
|
||||
"title": "Product Engineering",
|
||||
"start_date": frappe.utils.add_days(current_date, 45),
|
||||
"end_date": frappe.utils.add_days(current_date, 55)
|
||||
},
|
||||
{
|
||||
"title": "Supplier Contracts",
|
||||
"start_date": frappe.utils.add_days(current_date, 55),
|
||||
"end_date": frappe.utils.add_days(current_date, 70)
|
||||
},
|
||||
{
|
||||
"title": "Design and Build Fixtures",
|
||||
"start_date": frappe.utils.add_days(current_date, 45),
|
||||
"end_date": frappe.utils.add_days(current_date, 65)
|
||||
},
|
||||
{
|
||||
"title": "Test Run",
|
||||
"start_date": frappe.utils.add_days(current_date, 70),
|
||||
"end_date": frappe.utils.add_days(current_date, 80)
|
||||
},
|
||||
{
|
||||
"title": "Launch",
|
||||
"start_date": frappe.utils.add_days(current_date, 80),
|
||||
"end_date": frappe.utils.add_days(current_date, 90)
|
||||
},
|
||||
])
|
||||
project.insert()
|
||||
|
@ -66,7 +66,7 @@ def make_opportunity(domain):
|
||||
b = frappe.get_doc({
|
||||
"doctype": "Opportunity",
|
||||
"opportunity_from": "Customer",
|
||||
"customer": get_random("Customer"),
|
||||
"party_name": frappe.get_value("Customer", get_random("Customer"), 'name'),
|
||||
"opportunity_type": "Sales",
|
||||
"with_items": 1,
|
||||
"transaction_date": frappe.flags.current_date,
|
||||
|
@ -29,7 +29,8 @@ def sync_sales_order(order, request_id=None):
|
||||
validate_item(order, shopify_settings)
|
||||
create_order(order, shopify_settings)
|
||||
except Exception as e:
|
||||
make_shopify_log(status="Error", message=e.message, exception=False)
|
||||
make_shopify_log(status="Error", exception=e)
|
||||
|
||||
else:
|
||||
make_shopify_log(status="Success")
|
||||
|
||||
@ -42,9 +43,9 @@ def prepare_sales_invoice(order, request_id=None):
|
||||
sales_order = get_sales_order(cstr(order['id']))
|
||||
if sales_order:
|
||||
create_sales_invoice(order, shopify_settings, sales_order)
|
||||
make_shopify_log(status="Success")
|
||||
except Exception:
|
||||
make_shopify_log(status="Error", exception=True)
|
||||
make_shopify_log(status="Success")
|
||||
except Exception as e:
|
||||
make_shopify_log(status="Error", exception=e, rollback=True)
|
||||
|
||||
def prepare_delivery_note(order, request_id=None):
|
||||
frappe.set_user('Administrator')
|
||||
@ -56,8 +57,8 @@ def prepare_delivery_note(order, request_id=None):
|
||||
if sales_order:
|
||||
create_delivery_note(order, shopify_settings, sales_order)
|
||||
make_shopify_log(status="Success")
|
||||
except Exception:
|
||||
make_shopify_log(status="Error", exception=True)
|
||||
except Exception as e:
|
||||
make_shopify_log(status="Error", exception=e, rollback=True)
|
||||
|
||||
def get_sales_order(shopify_order_id):
|
||||
sales_order = frappe.db.get_value("Sales Order", filters={"shopify_order_id": shopify_order_id})
|
||||
@ -97,7 +98,7 @@ def create_sales_order(shopify_order, shopify_settings, company=None):
|
||||
message = 'Following items are exists in order but relevant record not found in Product master'
|
||||
message += "\n" + ", ".join(product_not_exists)
|
||||
|
||||
make_shopify_log(status="Error", message=message, exception=True)
|
||||
make_shopify_log(status="Error", exception=e, rollback=True)
|
||||
|
||||
return ''
|
||||
|
||||
|
@ -12,23 +12,38 @@ class ShopifyLog(Document):
|
||||
pass
|
||||
|
||||
|
||||
def make_shopify_log(status="Queued", message=None, exception=False):
|
||||
def make_shopify_log(status="Queued", exception=None, rollback=False):
|
||||
# if name not provided by log calling method then fetch existing queued state log
|
||||
make_new = False
|
||||
|
||||
if not frappe.flags.request_id:
|
||||
return
|
||||
make_new = True
|
||||
|
||||
log = frappe.get_doc("Shopify Log", frappe.flags.request_id)
|
||||
|
||||
if exception:
|
||||
if rollback:
|
||||
frappe.db.rollback()
|
||||
log = frappe.get_doc({"doctype":"Shopify Log"}).insert(ignore_permissions=True)
|
||||
|
||||
log.message = message if message else ''
|
||||
if make_new:
|
||||
log = frappe.get_doc({"doctype":"Shopify Log"}).insert(ignore_permissions=True)
|
||||
else:
|
||||
log = log = frappe.get_doc("Shopify Log", frappe.flags.request_id)
|
||||
|
||||
log.message = get_message(exception)
|
||||
log.traceback = frappe.get_traceback()
|
||||
log.status = status
|
||||
log.save(ignore_permissions=True)
|
||||
frappe.db.commit()
|
||||
|
||||
def get_message(exception):
|
||||
message = None
|
||||
|
||||
if hasattr(exception, 'message'):
|
||||
message = exception.message
|
||||
elif hasattr(exception, '__str__'):
|
||||
message = e.__str__()
|
||||
else:
|
||||
message = "Something went wrong while syncing"
|
||||
return message
|
||||
|
||||
def dump_request_data(data, event="create/order"):
|
||||
event_mapper = {
|
||||
"orders/create": get_webhook_address(connector_name='shopify_connection', method="sync_sales_order", exclude_uri=True),
|
||||
@ -43,11 +58,11 @@ def dump_request_data(data, event="create/order"):
|
||||
}).insert(ignore_permissions=True)
|
||||
|
||||
frappe.db.commit()
|
||||
frappe.enqueue(method=event_mapper[event], queue='short', timeout=300, is_async=True,
|
||||
frappe.enqueue(method=event_mapper[event], queue='short', timeout=300, is_async=True,
|
||||
**{"order": data, "request_id": log.name})
|
||||
|
||||
@frappe.whitelist()
|
||||
def resync(method, name, request_data):
|
||||
frappe.db.set_value("Shopify Log", name, "status", "Queued", update_modified=False)
|
||||
frappe.enqueue(method=method, queue='short', timeout=300, is_async=True,
|
||||
frappe.enqueue(method=method, queue='short', timeout=300, is_async=True,
|
||||
**{"order": json.loads(request_data), "request_id": name})
|
||||
|
@ -30,13 +30,9 @@ class ShopifySettings(Document):
|
||||
# url = get_shopify_url('admin/webhooks.json', self)
|
||||
created_webhooks = [d.method for d in self.webhooks]
|
||||
url = get_shopify_url('admin/api/2019-04/webhooks.json', self)
|
||||
print('url', url)
|
||||
for method in webhooks:
|
||||
print('method', method)
|
||||
session = get_request_session()
|
||||
print('session', session)
|
||||
try:
|
||||
print(get_header(self))
|
||||
d = session.post(url, data=json.dumps({
|
||||
"webhook": {
|
||||
"topic": method,
|
||||
@ -44,7 +40,6 @@ class ShopifySettings(Document):
|
||||
"format": "json"
|
||||
}
|
||||
}), headers=get_header(self))
|
||||
print('d', d.json())
|
||||
d.raise_for_status()
|
||||
self.update_webhook_table(method, d.json())
|
||||
except Exception as e:
|
||||
@ -67,7 +62,6 @@ class ShopifySettings(Document):
|
||||
self.remove(d)
|
||||
|
||||
def update_webhook_table(self, method, res):
|
||||
print('update')
|
||||
self.append("webhooks", {
|
||||
"webhook_id": res['webhook']['id'],
|
||||
"method": method
|
||||
@ -75,7 +69,6 @@ class ShopifySettings(Document):
|
||||
|
||||
def get_shopify_url(path, settings):
|
||||
if settings.app_type == "Private":
|
||||
print(settings.api_key, settings.get_password('password'), settings.shopify_url, path)
|
||||
return 'https://{}:{}@{}/{}'.format(settings.api_key, settings.get_password('password'), settings.shopify_url, path)
|
||||
else:
|
||||
return 'https://{}/{}'.format(settings.shopify_url, path)
|
||||
|
@ -5,3 +5,4 @@ import frappe
|
||||
class PartyFrozen(frappe.ValidationError): pass
|
||||
class InvalidAccountCurrency(frappe.ValidationError): pass
|
||||
class InvalidCurrency(frappe.ValidationError): pass
|
||||
class PartyDisabled(frappe.ValidationError):pass
|
||||
|
@ -234,7 +234,7 @@ var show_patient_vital_charts = function(patient, me, btn_show_id, pts, title) {
|
||||
<a class='btn btn-default btn-xs btn-show-chart' data-show-chart-id='temperature' \
|
||||
data-pts='°C or °F' data-title='Temperature'>Temperature</a>\
|
||||
<a class='btn btn-default btn-xs btn-show-chart' data-show-chart-id='bmi' \
|
||||
data-pts='bmi' data-title='BMI'>BMI</a></div>";
|
||||
data-pts='' data-title='BMI'>BMI</a></div>";
|
||||
me.page.main.find(".show_chart_btns").html(show_chart_btns_html);
|
||||
var data = r.message;
|
||||
let labels = [], datasets = [];
|
||||
@ -275,7 +275,7 @@ var show_patient_vital_charts = function(patient, me, btn_show_id, pts, title) {
|
||||
datasets.push({name: "Heart Rate / Pulse", values: pulse, chartType:'line'});
|
||||
datasets.push({name: "Respiratory Rate", values: respiratory_rate, chartType:'line'});
|
||||
}
|
||||
new Chart( ".patient_vital_charts", {
|
||||
new frappe.Chart( ".patient_vital_charts", {
|
||||
data: {
|
||||
labels: labels,
|
||||
datasets: datasets
|
||||
@ -283,7 +283,7 @@ var show_patient_vital_charts = function(patient, me, btn_show_id, pts, title) {
|
||||
|
||||
title: title,
|
||||
type: 'axis-mixed', // 'axis-mixed', 'bar', 'line', 'pie', 'percentage'
|
||||
height: 150,
|
||||
height: 200,
|
||||
colors: ['purple', '#ffa3ef', 'light-blue'],
|
||||
|
||||
tooltipOptions: {
|
||||
|
228
erpnext/hooks.py
228
erpnext/hooks.py
@ -45,7 +45,10 @@ update_and_get_user_progress = "erpnext.utilities.user_progress_utils.update_def
|
||||
leaderboards = "erpnext.startup.leaderboard.get_leaderboards"
|
||||
|
||||
|
||||
on_session_creation = "erpnext.shopping_cart.utils.set_cart_count"
|
||||
on_session_creation = [
|
||||
"erpnext.portal.utils.create_customer_or_supplier",
|
||||
"erpnext.shopping_cart.utils.set_cart_count"
|
||||
]
|
||||
on_logout = "erpnext.shopping_cart.utils.clear_cart_count"
|
||||
|
||||
treeviews = ['Account', 'Cost Center', 'Warehouse', 'Item Group', 'Customer Group', 'Sales Person', 'Territory', 'Assessment Group', 'Department']
|
||||
@ -102,6 +105,20 @@ website_route_rules = [
|
||||
"parents": [{"label": _("Supplier Quotation"), "route": "supplier-quotations"}]
|
||||
}
|
||||
},
|
||||
{"from_route": "/purchase-orders", "to_route": "Purchase Order"},
|
||||
{"from_route": "/purchase-orders/<path:name>", "to_route": "order",
|
||||
"defaults": {
|
||||
"doctype": "Purchase Order",
|
||||
"parents": [{"label": _("Purchase Order"), "route": "purchase-orders"}]
|
||||
}
|
||||
},
|
||||
{"from_route": "/purchase-invoices", "to_route": "Purchase Invoice"},
|
||||
{"from_route": "/purchase-invoices/<path:name>", "to_route": "order",
|
||||
"defaults": {
|
||||
"doctype": "Purchase Invoice",
|
||||
"parents": [{"label": _("Purchase Invoice"), "route": "purchase-invoices"}]
|
||||
}
|
||||
},
|
||||
{"from_route": "/quotations", "to_route": "Quotation"},
|
||||
{"from_route": "/quotations/<path:name>", "to_route": "order",
|
||||
"defaults": {
|
||||
@ -148,6 +165,8 @@ standard_portal_menu_items = [
|
||||
{"title": _("Projects"), "route": "/project", "reference_doctype": "Project"},
|
||||
{"title": _("Request for Quotations"), "route": "/rfq", "reference_doctype": "Request for Quotation", "role": "Supplier"},
|
||||
{"title": _("Supplier Quotation"), "route": "/supplier-quotations", "reference_doctype": "Supplier Quotation", "role": "Supplier"},
|
||||
{"title": _("Purchase Orders"), "route": "/purchase-orders", "reference_doctype": "Purchase Order", "role": "Supplier"},
|
||||
{"title": _("Purchase Invoices"), "route": "/purchase-invoices", "reference_doctype": "Purchase Invoice", "role": "Supplier"},
|
||||
{"title": _("Quotations"), "route": "/quotations", "reference_doctype": "Quotation", "role":"Customer"},
|
||||
{"title": _("Orders"), "route": "/orders", "reference_doctype": "Sales Order", "role":"Customer"},
|
||||
{"title": _("Invoices"), "route": "/invoices", "reference_doctype": "Sales Invoice", "role":"Customer"},
|
||||
@ -160,8 +179,8 @@ standard_portal_menu_items = [
|
||||
{"title": _("Patient Appointment"), "route": "/patient-appointments", "reference_doctype": "Patient Appointment", "role":"Patient"},
|
||||
{"title": _("Fees"), "route": "/fees", "reference_doctype": "Fees", "role":"Student"},
|
||||
{"title": _("Newsletter"), "route": "/newsletters", "reference_doctype": "Newsletter"},
|
||||
{"title": _("Admission"), "route": "/admissions", "reference_doctype": "Student Admission"},
|
||||
{"title": _("Certification"), "route": "/certification", "reference_doctype": "Certification Application"},
|
||||
{"title": _("Admission"), "route": "/admissions", "reference_doctype": "Student Admission", "role": "Student"},
|
||||
{"title": _("Certification"), "route": "/certification", "reference_doctype": "Certification Application", "role": "Non Profit Portal User"},
|
||||
{"title": _("Material Request"), "route": "/material-requests", "reference_doctype": "Material Request", "role": "Customer"},
|
||||
]
|
||||
|
||||
@ -181,6 +200,8 @@ has_website_permission = {
|
||||
"Quotation": "erpnext.controllers.website_list_for_contact.has_website_permission",
|
||||
"Sales Invoice": "erpnext.controllers.website_list_for_contact.has_website_permission",
|
||||
"Supplier Quotation": "erpnext.controllers.website_list_for_contact.has_website_permission",
|
||||
"Purchase Order": "erpnext.controllers.website_list_for_contact.has_website_permission",
|
||||
"Purchase Invoice": "erpnext.controllers.website_list_for_contact.has_website_permission",
|
||||
"Material Request": "erpnext.controllers.website_list_for_contact.has_website_permission",
|
||||
"Delivery Note": "erpnext.controllers.website_list_for_contact.has_website_permission",
|
||||
"Issue": "erpnext.support.doctype.issue.issue.has_website_permission",
|
||||
@ -355,52 +376,155 @@ user_privacy_documents = [
|
||||
}
|
||||
]
|
||||
|
||||
global_search_doctypes = [
|
||||
{"doctype": "Customer", "index": 0},
|
||||
{"doctype": "Supplier", "index": 1},
|
||||
{"doctype": "Item", "index": 2},
|
||||
{"doctype": "Warehouse", "index": 3},
|
||||
{"doctype": "Account", "index": 4},
|
||||
{"doctype": "Employee", "index": 5},
|
||||
{"doctype": "BOM", "index": 6},
|
||||
{"doctype": "Sales Invoice", "index": 7},
|
||||
{"doctype": "Sales Order", "index": 8},
|
||||
{"doctype": "Quotation", "index": 9},
|
||||
{"doctype": "Work Order", "index": 10},
|
||||
{"doctype": "Purchase Receipt", "index": 11},
|
||||
{"doctype": "Purchase Invoice", "index": 12},
|
||||
{"doctype": "Delivery Note", "index": 13},
|
||||
{"doctype": "Stock Entry", "index": 14},
|
||||
{"doctype": "Material Request", "index": 15},
|
||||
{"doctype": "Delivery Trip", "index": 16},
|
||||
{"doctype": "Pick List", "index": 17},
|
||||
{"doctype": "Salary Slip", "index": 18},
|
||||
{"doctype": "Leave Application", "index": 19},
|
||||
{"doctype": "Expense Claim", "index": 20},
|
||||
{"doctype": "Payment Entry", "index": 21},
|
||||
{"doctype": "Lead", "index": 22},
|
||||
{"doctype": "Opportunity", "index": 23},
|
||||
{"doctype": "Item Price", "index": 24},
|
||||
{"doctype": "Purchase Taxes and Charges Template", "index": 25},
|
||||
{"doctype": "Sales Taxes and Charges", "index": 26},
|
||||
{"doctype": "Asset", "index": 27},
|
||||
{"doctype": "Project", "index": 28},
|
||||
{"doctype": "Task", "index": 29},
|
||||
{"doctype": "Timesheet", "index": 30},
|
||||
{"doctype": "Issue", "index": 31},
|
||||
{"doctype": "Serial No", "index": 32},
|
||||
{"doctype": "Batch", "index": 33},
|
||||
{"doctype": "Branch", "index": 34},
|
||||
{"doctype": "Department", "index": 35},
|
||||
{"doctype": "Employee Grade", "index": 36},
|
||||
{"doctype": "Designation", "index": 37},
|
||||
{"doctype": "Job Opening", "index": 38},
|
||||
{"doctype": "Job Applicant", "index": 39},
|
||||
{"doctype": "Job Offer", "index": 40},
|
||||
{"doctype": "Salary Structure Assignment", "index": 41},
|
||||
{"doctype": "Appraisal", "index": 42},
|
||||
{"doctype": "Loan", "index": 43},
|
||||
{"doctype": "Maintenance Schedule", "index": 44},
|
||||
{"doctype": "Maintenance Visit", "index": 45},
|
||||
{"doctype": "Warranty Claim", "index": 46},
|
||||
]
|
||||
# ERPNext doctypes for Global Search
|
||||
global_search_doctypes = {
|
||||
"Default": [
|
||||
{"doctype": "Customer", "index": 0},
|
||||
{"doctype": "Supplier", "index": 1},
|
||||
{"doctype": "Item", "index": 2},
|
||||
{"doctype": "Warehouse", "index": 3},
|
||||
{"doctype": "Account", "index": 4},
|
||||
{"doctype": "Employee", "index": 5},
|
||||
{"doctype": "BOM", "index": 6},
|
||||
{"doctype": "Sales Invoice", "index": 7},
|
||||
{"doctype": "Sales Order", "index": 8},
|
||||
{"doctype": "Quotation", "index": 9},
|
||||
{"doctype": "Work Order", "index": 10},
|
||||
{"doctype": "Purchase Receipt", "index": 11},
|
||||
{"doctype": "Purchase Invoice", "index": 12},
|
||||
{"doctype": "Delivery Note", "index": 13},
|
||||
{"doctype": "Stock Entry", "index": 14},
|
||||
{"doctype": "Material Request", "index": 15},
|
||||
{"doctype": "Delivery Trip", "index": 16},
|
||||
{"doctype": "Pick List", "index": 17},
|
||||
{"doctype": "Salary Slip", "index": 18},
|
||||
{"doctype": "Leave Application", "index": 19},
|
||||
{"doctype": "Expense Claim", "index": 20},
|
||||
{"doctype": "Payment Entry", "index": 21},
|
||||
{"doctype": "Lead", "index": 22},
|
||||
{"doctype": "Opportunity", "index": 23},
|
||||
{"doctype": "Item Price", "index": 24},
|
||||
{"doctype": "Purchase Taxes and Charges Template", "index": 25},
|
||||
{"doctype": "Sales Taxes and Charges", "index": 26},
|
||||
{"doctype": "Asset", "index": 27},
|
||||
{"doctype": "Project", "index": 28},
|
||||
{"doctype": "Task", "index": 29},
|
||||
{"doctype": "Timesheet", "index": 30},
|
||||
{"doctype": "Issue", "index": 31},
|
||||
{"doctype": "Serial No", "index": 32},
|
||||
{"doctype": "Batch", "index": 33},
|
||||
{"doctype": "Branch", "index": 34},
|
||||
{"doctype": "Department", "index": 35},
|
||||
{"doctype": "Employee Grade", "index": 36},
|
||||
{"doctype": "Designation", "index": 37},
|
||||
{"doctype": "Job Opening", "index": 38},
|
||||
{"doctype": "Job Applicant", "index": 39},
|
||||
{"doctype": "Job Offer", "index": 40},
|
||||
{"doctype": "Salary Structure Assignment", "index": 41},
|
||||
{"doctype": "Appraisal", "index": 42},
|
||||
{"doctype": "Loan", "index": 43},
|
||||
{"doctype": "Maintenance Schedule", "index": 44},
|
||||
{"doctype": "Maintenance Visit", "index": 45},
|
||||
{"doctype": "Warranty Claim", "index": 46},
|
||||
],
|
||||
"Healthcare": [
|
||||
{'doctype': 'Patient', 'index': 1},
|
||||
{'doctype': 'Medical Department', 'index': 2},
|
||||
{'doctype': 'Vital Signs', 'index': 3},
|
||||
{'doctype': 'Healthcare Practitioner', 'index': 4},
|
||||
{'doctype': 'Patient Appointment', 'index': 5},
|
||||
{'doctype': 'Healthcare Service Unit', 'index': 6},
|
||||
{'doctype': 'Patient Encounter', 'index': 7},
|
||||
{'doctype': 'Antibiotic', 'index': 8},
|
||||
{'doctype': 'Diagnosis', 'index': 9},
|
||||
{'doctype': 'Lab Test', 'index': 10},
|
||||
{'doctype': 'Clinical Procedure', 'index': 11},
|
||||
{'doctype': 'Inpatient Record', 'index': 12},
|
||||
{'doctype': 'Sample Collection', 'index': 13},
|
||||
{'doctype': 'Patient Medical Record', 'index': 14},
|
||||
{'doctype': 'Appointment Type', 'index': 15},
|
||||
{'doctype': 'Fee Validity', 'index': 16},
|
||||
{'doctype': 'Practitioner Schedule', 'index': 17},
|
||||
{'doctype': 'Dosage Form', 'index': 18},
|
||||
{'doctype': 'Lab Test Sample', 'index': 19},
|
||||
{'doctype': 'Prescription Duration', 'index': 20},
|
||||
{'doctype': 'Prescription Dosage', 'index': 21},
|
||||
{'doctype': 'Sensitivity', 'index': 22},
|
||||
{'doctype': 'Complaint', 'index': 23},
|
||||
{'doctype': 'Medical Code', 'index': 24},
|
||||
],
|
||||
"Education": [
|
||||
{'doctype': 'Article', 'index': 1},
|
||||
{'doctype': 'Video', 'index': 2},
|
||||
{'doctype': 'Topic', 'index': 3},
|
||||
{'doctype': 'Course', 'index': 4},
|
||||
{'doctype': 'Program', 'index': 5},
|
||||
{'doctype': 'Quiz', 'index': 6},
|
||||
{'doctype': 'Question', 'index': 7},
|
||||
{'doctype': 'Fee Schedule', 'index': 8},
|
||||
{'doctype': 'Fee Structure', 'index': 9},
|
||||
{'doctype': 'Fees', 'index': 10},
|
||||
{'doctype': 'Student Group', 'index': 11},
|
||||
{'doctype': 'Student', 'index': 12},
|
||||
{'doctype': 'Instructor', 'index': 13},
|
||||
{'doctype': 'Course Activity', 'index': 14},
|
||||
{'doctype': 'Quiz Activity', 'index': 15},
|
||||
{'doctype': 'Course Enrollment', 'index': 16},
|
||||
{'doctype': 'Program Enrollment', 'index': 17},
|
||||
{'doctype': 'Student Language', 'index': 18},
|
||||
{'doctype': 'Student Applicant', 'index': 19},
|
||||
{'doctype': 'Assessment Result', 'index': 20},
|
||||
{'doctype': 'Assessment Plan', 'index': 21},
|
||||
{'doctype': 'Grading Scale', 'index': 22},
|
||||
{'doctype': 'Guardian', 'index': 23},
|
||||
{'doctype': 'Student Leave Application', 'index': 24},
|
||||
{'doctype': 'Student Log', 'index': 25},
|
||||
{'doctype': 'Room', 'index': 26},
|
||||
{'doctype': 'Course Schedule', 'index': 27},
|
||||
{'doctype': 'Student Attendance', 'index': 28},
|
||||
{'doctype': 'Announcement', 'index': 29},
|
||||
{'doctype': 'Student Category', 'index': 30},
|
||||
{'doctype': 'Assessment Group', 'index': 31},
|
||||
{'doctype': 'Student Batch Name', 'index': 32},
|
||||
{'doctype': 'Assessment Criteria', 'index': 33},
|
||||
{'doctype': 'Academic Year', 'index': 34},
|
||||
{'doctype': 'Academic Term', 'index': 35},
|
||||
{'doctype': 'School House', 'index': 36},
|
||||
{'doctype': 'Student Admission', 'index': 37},
|
||||
{'doctype': 'Fee Category', 'index': 38},
|
||||
{'doctype': 'Assessment Code', 'index': 39},
|
||||
{'doctype': 'Discussion', 'index': 40},
|
||||
],
|
||||
"Agriculture": [
|
||||
{'doctype': 'Weather', 'index': 1},
|
||||
{'doctype': 'Soil Texture', 'index': 2},
|
||||
{'doctype': 'Water Analysis', 'index': 3},
|
||||
{'doctype': 'Soil Analysis', 'index': 4},
|
||||
{'doctype': 'Plant Analysis', 'index': 5},
|
||||
{'doctype': 'Agriculture Analysis Criteria', 'index': 6},
|
||||
{'doctype': 'Disease', 'index': 7},
|
||||
{'doctype': 'Crop', 'index': 8},
|
||||
{'doctype': 'Fertilizer', 'index': 9},
|
||||
{'doctype': 'Crop Cycle', 'index': 10}
|
||||
],
|
||||
"Non Profit": [
|
||||
{'doctype': 'Certified Consultant', 'index': 1},
|
||||
{'doctype': 'Certification Application', 'index': 2},
|
||||
{'doctype': 'Volunteer', 'index': 3},
|
||||
{'doctype': 'Membership', 'index': 4},
|
||||
{'doctype': 'Member', 'index': 5},
|
||||
{'doctype': 'Donor', 'index': 6},
|
||||
{'doctype': 'Chapter', 'index': 7},
|
||||
{'doctype': 'Grant Application', 'index': 8},
|
||||
{'doctype': 'Volunteer Type', 'index': 9},
|
||||
{'doctype': 'Donor Type', 'index': 10},
|
||||
{'doctype': 'Membership Type', 'index': 11}
|
||||
],
|
||||
"Hospitality": [
|
||||
{'doctype': 'Hotel Room', 'index': 0},
|
||||
{'doctype': 'Hotel Room Reservation', 'index': 1},
|
||||
{'doctype': 'Hotel Room Pricing', 'index': 2},
|
||||
{'doctype': 'Hotel Room Package', 'index': 3},
|
||||
{'doctype': 'Hotel Room Type', 'index': 4}
|
||||
]
|
||||
}
|
@ -1,14 +1,36 @@
|
||||
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Driver', {
|
||||
frappe.ui.form.on("Driver", {
|
||||
setup: function(frm) {
|
||||
frm.set_query('transporter', function(){
|
||||
frm.set_query("transporter", function() {
|
||||
return {
|
||||
filters: {
|
||||
'is_transporter': 1
|
||||
is_transporter: 1
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
refresh: function(frm) {
|
||||
frm.set_query("address", function() {
|
||||
return {
|
||||
filters: {
|
||||
is_your_company_address: !frm.doc.transporter ? 1 : 0
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
transporter: function(frm, cdt, cdn) {
|
||||
// this assumes that supplier's address has same title as supplier's name
|
||||
frappe.db
|
||||
.get_doc("Address", null, { address_title: frm.doc.transporter })
|
||||
.then(r => {
|
||||
frappe.model.set_value(cdt, cdn, "address", r.name);
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -404,8 +404,11 @@ def get_number_of_leave_days(employee, leave_type, from_date, to_date, half_day
|
||||
if cint(half_day) == 1:
|
||||
if from_date == to_date:
|
||||
number_of_days = 0.5
|
||||
else:
|
||||
elif half_day_date and half_day_date <= to_date:
|
||||
number_of_days = date_diff(to_date, from_date) + .5
|
||||
else:
|
||||
number_of_days = date_diff(to_date, from_date) + 1
|
||||
|
||||
else:
|
||||
number_of_days = date_diff(to_date, from_date) + 1
|
||||
|
||||
@ -549,8 +552,16 @@ def get_leaves_for_period(employee, leave_type, from_date, to_date):
|
||||
if leave_entry.to_date > getdate(to_date):
|
||||
leave_entry.to_date = to_date
|
||||
|
||||
half_day = 0
|
||||
half_day_date = None
|
||||
# fetch half day date for leaves with half days
|
||||
if leave_entry.leaves % 1:
|
||||
half_day = 1
|
||||
half_day_date = frappe.db.get_value('Leave Application',
|
||||
{'name': leave_entry.transaction_name}, ['half_day_date'])
|
||||
|
||||
leave_days += get_number_of_leave_days(employee, leave_type,
|
||||
leave_entry.from_date, leave_entry.to_date) * -1
|
||||
leave_entry.from_date, leave_entry.to_date, half_day, half_day_date) * -1
|
||||
|
||||
return leave_days
|
||||
|
||||
@ -562,7 +573,7 @@ def skip_expiry_leaves(leave_entry, date):
|
||||
def get_leave_entries(employee, leave_type, from_date, to_date):
|
||||
''' Returns leave entries between from_date and to_date '''
|
||||
return frappe.db.sql("""
|
||||
select employee, leave_type, from_date, to_date, leaves, transaction_type, is_carry_forward
|
||||
select employee, leave_type, from_date, to_date, leaves, transaction_type, is_carry_forward, transaction_name
|
||||
from `tabLeave Ledger Entry`
|
||||
where employee=%(employee)s and leave_type=%(leave_type)s
|
||||
and docstatus=1
|
||||
|
@ -255,16 +255,19 @@ class SalarySlip(TransactionBase):
|
||||
for d in range(working_days):
|
||||
dt = add_days(cstr(getdate(self.start_date)), d)
|
||||
leave = frappe.db.sql("""
|
||||
select t1.name, t1.half_day
|
||||
from `tabLeave Application` t1, `tabLeave Type` t2
|
||||
where t2.name = t1.leave_type
|
||||
and t2.is_lwp = 1
|
||||
and t1.docstatus = 1
|
||||
and t1.employee = %(employee)s
|
||||
and CASE WHEN t2.include_holiday != 1 THEN %(dt)s not in ('{0}') and %(dt)s between from_date and to_date and ifnull(t1.salary_slip, '') = ''
|
||||
SELECT t1.name,
|
||||
CASE WHEN t1.half_day_date = %(dt)s or t1.to_date = t1.from_date
|
||||
THEN t1.half_day else 0 END
|
||||
FROM `tabLeave Application` t1, `tabLeave Type` t2
|
||||
WHERE t2.name = t1.leave_type
|
||||
AND t2.is_lwp = 1
|
||||
AND t1.docstatus = 1
|
||||
AND t1.employee = %(employee)s
|
||||
AND CASE WHEN t2.include_holiday != 1 THEN %(dt)s not in ('{0}') and %(dt)s between from_date and to_date and ifnull(t1.salary_slip, '') = ''
|
||||
WHEN t2.include_holiday THEN %(dt)s between from_date and to_date and ifnull(t1.salary_slip, '') = ''
|
||||
END
|
||||
""".format(holidays), {"employee": self.employee, "dt": dt})
|
||||
|
||||
if leave:
|
||||
lwp = cint(leave[0][1]) and (lwp + 0.5) or (lwp + 1)
|
||||
return lwp
|
||||
|
@ -4,6 +4,17 @@
|
||||
frappe.provide("erpnext.maintenance");
|
||||
|
||||
frappe.ui.form.on('Maintenance Visit', {
|
||||
refresh: function(frm) {
|
||||
//filters for serial_no based on item_code
|
||||
frm.set_query('serial_no', 'purposes', function(frm, cdt, cdn) {
|
||||
let item = locals[cdt][cdn];
|
||||
return {
|
||||
filters: {
|
||||
'item_code': item.item_code
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
setup: function(frm) {
|
||||
frm.set_query('contact_person', erpnext.queries.contact_query);
|
||||
frm.set_query('customer_address', erpnext.queries.address_query);
|
||||
|
@ -1,348 +1,137 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "hash",
|
||||
"beta": 0,
|
||||
"creation": "2013-02-22 01:28:06",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "Document",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"autoname": "hash",
|
||||
"creation": "2013-02-22 01:28:06",
|
||||
"doctype": "DocType",
|
||||
"document_type": "Document",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"item_code",
|
||||
"item_name",
|
||||
"serial_no",
|
||||
"description",
|
||||
"work_details",
|
||||
"service_person",
|
||||
"work_done",
|
||||
"prevdoc_doctype",
|
||||
"prevdoc_docname",
|
||||
"prevdoc_detail_docname"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "item_code",
|
||||
"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": "Item Code",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "item_code",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Item",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fieldname": "item_code",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Item Code",
|
||||
"oldfieldname": "item_code",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Item"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "item_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 1,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Item Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "item_name",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fetch_from": "item_code.item_name",
|
||||
"fieldname": "item_name",
|
||||
"fieldtype": "Data",
|
||||
"in_global_search": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Item Name",
|
||||
"oldfieldname": "item_name",
|
||||
"oldfieldtype": "Data",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "serial_no",
|
||||
"fieldtype": "Small Text",
|
||||
"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": "Serial No",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "serial_no",
|
||||
"oldfieldtype": "Small Text",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fieldname": "serial_no",
|
||||
"fieldtype": "Link",
|
||||
"label": "Serial No",
|
||||
"oldfieldname": "serial_no",
|
||||
"oldfieldtype": "Small Text",
|
||||
"options": "Serial No"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Text Editor",
|
||||
"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": "Description",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "description",
|
||||
"oldfieldtype": "Small Text",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "300px",
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0,
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Text Editor",
|
||||
"in_list_view": 1,
|
||||
"label": "Description",
|
||||
"oldfieldname": "description",
|
||||
"oldfieldtype": "Small Text",
|
||||
"print_width": "300px",
|
||||
"reqd": 1,
|
||||
"width": "300px"
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "work_details",
|
||||
"fieldtype": "Section 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,
|
||||
"label": "",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fieldname": "work_details",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "service_person",
|
||||
"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": "Sales Person",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "service_person",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Sales Person",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fieldname": "service_person",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Sales Person",
|
||||
"oldfieldname": "service_person",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Sales Person",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "work_done",
|
||||
"fieldtype": "Small Text",
|
||||
"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": "Work Done",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "work_done",
|
||||
"oldfieldtype": "Small Text",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fieldname": "work_done",
|
||||
"fieldtype": "Small Text",
|
||||
"in_list_view": 1,
|
||||
"label": "Work Done",
|
||||
"oldfieldname": "work_done",
|
||||
"oldfieldtype": "Small Text",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "prevdoc_doctype",
|
||||
"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": "Document Type",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "prevdoc_doctype",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "DocType",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "150px",
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 1,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0,
|
||||
"fieldname": "prevdoc_doctype",
|
||||
"fieldtype": "Link",
|
||||
"label": "Document Type",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "prevdoc_doctype",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "DocType",
|
||||
"print_hide": 1,
|
||||
"print_width": "150px",
|
||||
"read_only": 1,
|
||||
"report_hide": 1,
|
||||
"width": "150px"
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "prevdoc_docname",
|
||||
"fieldtype": "Dynamic 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": "Against Document No",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "prevdoc_docname",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "prevdoc_doctype",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "160px",
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 1,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0,
|
||||
"fieldname": "prevdoc_docname",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"label": "Against Document No",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "prevdoc_docname",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "prevdoc_doctype",
|
||||
"print_hide": 1,
|
||||
"print_width": "160px",
|
||||
"read_only": 1,
|
||||
"report_hide": 1,
|
||||
"width": "160px"
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "prevdoc_detail_docname",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Against Document Detail No",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "prevdoc_detail_docname",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "160px",
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 1,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0,
|
||||
"fieldname": "prevdoc_detail_docname",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"label": "Against Document Detail No",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "prevdoc_detail_docname",
|
||||
"oldfieldtype": "Data",
|
||||
"print_hide": 1,
|
||||
"print_width": "160px",
|
||||
"read_only": 1,
|
||||
"report_hide": 1,
|
||||
"width": "160px"
|
||||
}
|
||||
],
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 1,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-02-17 17:06:11.910266",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Maintenance",
|
||||
"name": "Maintenance Visit Purpose",
|
||||
"owner": "ashwini@webnotestech.com",
|
||||
"permissions": [],
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2019-10-03 14:55:52.786805",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Maintenance",
|
||||
"name": "Maintenance Visit Purpose",
|
||||
"owner": "ashwini@webnotestech.com",
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
@ -12,6 +12,7 @@ frappe.ui.form.on('Blanket Order', {
|
||||
},
|
||||
|
||||
refresh: function(frm) {
|
||||
erpnext.hide_company();
|
||||
if (frm.doc.customer && frm.doc.docstatus === 1) {
|
||||
frm.add_custom_button(__('View Orders'), function() {
|
||||
frappe.set_route('List', 'Sales Order', {blanket_order: frm.doc.name});
|
||||
@ -51,11 +52,19 @@ frappe.ui.form.on('Blanket Order', {
|
||||
|
||||
set_tc_name_filter: function(frm) {
|
||||
if (frm.doc.blanket_order_type === 'Selling') {
|
||||
frm.set_df_property("customer","reqd", 1);
|
||||
frm.set_df_property("supplier","reqd", 0);
|
||||
frm.set_value("supplier", "");
|
||||
|
||||
frm.set_query("tc_name", function() {
|
||||
return { filters: { selling: 1 } };
|
||||
});
|
||||
}
|
||||
if (frm.doc.blanket_order_type === 'Purchasing') {
|
||||
frm.set_df_property("supplier","reqd", 1);
|
||||
frm.set_df_property("customer","reqd", 0);
|
||||
frm.set_value("customer", "");
|
||||
|
||||
frm.set_query("tc_name", function() {
|
||||
return { filters: { buying: 1 } };
|
||||
});
|
||||
|
@ -88,7 +88,8 @@
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"label": "Company",
|
||||
"options": "Company"
|
||||
"options": "Company",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_12",
|
||||
@ -128,7 +129,7 @@
|
||||
}
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"modified": "2019-06-19 11:59:09.279607",
|
||||
"modified": "2019-10-16 13:38:32.302316",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Blanket Order",
|
||||
|
@ -4,13 +4,21 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.utils import flt
|
||||
from frappe import _
|
||||
from frappe.utils import flt, getdate
|
||||
from frappe.model.document import Document
|
||||
from frappe.model.mapper import get_mapped_doc
|
||||
from erpnext.stock.doctype.item.item import get_item_defaults
|
||||
|
||||
|
||||
class BlanketOrder(Document):
|
||||
def validate(self):
|
||||
self.validate_dates()
|
||||
|
||||
def validate_dates(self):
|
||||
if getdate(self.from_date) > getdate(self.to_date):
|
||||
frappe.throw(_("From date cannot be greater than To date"))
|
||||
|
||||
def update_ordered_qty(self):
|
||||
ref_doctype = "Sales Order" if self.blanket_order_type == "Selling" else "Purchase Order"
|
||||
item_ordered_qty = frappe._dict(frappe.db.sql("""
|
||||
|
@ -117,7 +117,7 @@ frappe.ui.form.on("BOM", {
|
||||
args: {
|
||||
update_parent: true,
|
||||
from_child_bom:false,
|
||||
save: false
|
||||
save: frm.doc.docstatus === 1 ? true : false
|
||||
},
|
||||
callback: function(r) {
|
||||
refresh_field("items");
|
||||
|
@ -35,7 +35,8 @@ class BOM(WebsiteGenerator):
|
||||
# name can be BOM/ITEM/001, BOM/ITEM/001-1, BOM-ITEM-001, BOM-ITEM-001-1
|
||||
|
||||
# split by item
|
||||
names = [name.split(self.item)[-1][1:] for name in names]
|
||||
names = [name.split(self.item, 1) for name in names]
|
||||
names = [d[-1][1:] for d in filter(lambda x: len(x) > 1 and x[-1], names)]
|
||||
|
||||
# split by (-) if cancelled
|
||||
names = [cint(name.split('-')[-1]) for name in names]
|
||||
@ -173,7 +174,7 @@ class BOM(WebsiteGenerator):
|
||||
#Customer Provided parts will have zero rate
|
||||
if not frappe.db.get_value('Item', arg["item_code"], 'is_customer_provided_item'):
|
||||
if arg.get('bom_no') and self.set_rate_of_sub_assembly_item_based_on_bom:
|
||||
rate = self.get_bom_unitcost(arg['bom_no']) * (arg.get("conversion_factor") or 1)
|
||||
rate = flt(self.get_bom_unitcost(arg['bom_no'])) * (arg.get("conversion_factor") or 1)
|
||||
else:
|
||||
if self.rm_cost_as_per == 'Valuation Rate':
|
||||
rate = self.get_valuation_rate(arg) * (arg.get("conversion_factor") or 1)
|
||||
|
@ -558,7 +558,7 @@ def get_sales_orders(self):
|
||||
item_filter += " and so_item.item_code = %(item)s"
|
||||
|
||||
open_so = frappe.db.sql("""
|
||||
select distinct so.name, so.transaction_date, so.customer, so.base_grand_total
|
||||
select distinct so.name, so.transaction_date, so.customer, so.base_grand_total as grand_total
|
||||
from `tabSales Order` so, `tabSales Order Item` so_item
|
||||
where so_item.parent = so.name
|
||||
and so.docstatus = 1 and so.status not in ("Stopped", "Closed")
|
||||
|
@ -91,6 +91,16 @@ frappe.ui.form.on("Work Order", {
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_query("operation", "required_items", function() {
|
||||
return {
|
||||
query: "erpnext.manufacturing.doctype.work_order.work_order.get_bom_operations",
|
||||
filters: {
|
||||
'parent': frm.doc.bom_no,
|
||||
'parenttype': 'BOM'
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
// formatter for work order operation
|
||||
frm.set_indicator_formatter('operation',
|
||||
function(doc) { return (frm.doc.qty==doc.completed_qty) ? "green" : "orange"; });
|
||||
|
@ -64,7 +64,8 @@ class WorkOrder(Document):
|
||||
from `tabSales Order` so
|
||||
inner join `tabSales Order Item` so_item on so_item.parent = so.name
|
||||
left join `tabProduct Bundle Item` pk_item on so_item.item_code = pk_item.parent
|
||||
where so.name=%s and so.docstatus = 1 and (
|
||||
where so.name=%s and so.docstatus = 1
|
||||
and so.skip_delivery_note = 0 and (
|
||||
so_item.item_code=%s or
|
||||
pk_item.item_code=%s )
|
||||
""", (self.sales_order, self.production_item, self.production_item), as_dict=1)
|
||||
@ -78,6 +79,7 @@ class WorkOrder(Document):
|
||||
where so.name=%s
|
||||
and so.name=so_item.parent
|
||||
and so.name=packed_item.parent
|
||||
and so.skip_delivery_note = 0
|
||||
and so_item.item_code = packed_item.parent_item
|
||||
and so.docstatus = 1 and packed_item.item_code=%s
|
||||
""", (self.sales_order, self.production_item), as_dict=1)
|
||||
@ -477,6 +479,9 @@ class WorkOrder(Document):
|
||||
'include_item_in_manufacturing': item.include_item_in_manufacturing
|
||||
})
|
||||
|
||||
if not self.project:
|
||||
self.project = item.get("project")
|
||||
|
||||
self.set_available_qty()
|
||||
|
||||
def update_transaferred_qty_for_required_items(self):
|
||||
@ -543,6 +548,13 @@ class WorkOrder(Document):
|
||||
bom.set_bom_material_details()
|
||||
return bom
|
||||
|
||||
def get_bom_operations(doctype, txt, searchfield, start, page_len, filters):
|
||||
if txt:
|
||||
filters['operation'] = ('like', '%%%s%%' % txt)
|
||||
|
||||
return frappe.get_all('BOM Operation',
|
||||
filters = filters, fields = ['operation'], as_list=1)
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_item_details(item, project = None):
|
||||
res = frappe.db.sql("""
|
||||
|
@ -10,6 +10,7 @@ def execute():
|
||||
for last allocation """
|
||||
frappe.reload_doc("HR", "doctype", "Leave Ledger Entry")
|
||||
frappe.reload_doc("HR", "doctype", "Leave Encashment")
|
||||
frappe.reload_doc("HR", "doctype", "Leave Type")
|
||||
if frappe.db.a_row_exists("Leave Ledger Entry"):
|
||||
return
|
||||
|
||||
@ -84,4 +85,4 @@ def get_leaves_application_records():
|
||||
def get_leave_encashment_records():
|
||||
return frappe.get_all("Leave Encashment", filters={
|
||||
"docstatus": 1
|
||||
}, fields=['name', 'employee', 'leave_type', 'encashable_days', 'encashment_date'])
|
||||
}, fields=['name', 'employee', 'leave_type', 'encashable_days', 'encashment_date'])
|
||||
|
@ -41,7 +41,9 @@ def execute():
|
||||
item = frappe.get_doc("Item", item_code)
|
||||
item.set("taxes", [])
|
||||
item.append("taxes", {"item_tax_template": item_tax_template_name, "tax_category": ""})
|
||||
item.save()
|
||||
frappe.db.sql("delete from `tabItem Tax` where parent=%s and parenttype='Item'", item_code)
|
||||
for d in item.taxes:
|
||||
d.db_insert()
|
||||
|
||||
doctypes = [
|
||||
'Quotation', 'Sales Order', 'Delivery Note', 'Sales Invoice',
|
||||
|
@ -1,5 +1,8 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings import get_shopping_cart_settings
|
||||
from erpnext.shopping_cart.cart import get_debtors_account
|
||||
from frappe.utils.nestedset import get_root_of
|
||||
|
||||
def set_default_role(doc, method):
|
||||
'''Set customer, supplier, student, guardian based on email'''
|
||||
@ -21,3 +24,88 @@ def set_default_role(doc, method):
|
||||
doc.add_roles('Student')
|
||||
elif frappe.get_value('Guardian', dict(email_address=doc.email)) and 'Guardian' not in roles:
|
||||
doc.add_roles('Guardian')
|
||||
|
||||
def create_customer_or_supplier():
|
||||
'''Based on the default Role (Customer, Supplier), create a Customer / Supplier.
|
||||
Called on_session_creation hook.
|
||||
'''
|
||||
user = frappe.session.user
|
||||
|
||||
if frappe.db.get_value('User', user, 'user_type') != 'Website User':
|
||||
return
|
||||
|
||||
user_roles = frappe.get_roles()
|
||||
portal_settings = frappe.get_single('Portal Settings')
|
||||
default_role = portal_settings.default_role
|
||||
|
||||
if default_role not in ['Customer', 'Supplier']:
|
||||
return
|
||||
|
||||
# create customer / supplier if the user has that role
|
||||
if portal_settings.default_role and portal_settings.default_role in user_roles:
|
||||
doctype = portal_settings.default_role
|
||||
else:
|
||||
doctype = None
|
||||
|
||||
if not doctype:
|
||||
return
|
||||
|
||||
if party_exists(doctype, user):
|
||||
return
|
||||
|
||||
party = frappe.new_doc(doctype)
|
||||
fullname = frappe.utils.get_fullname(user)
|
||||
|
||||
if doctype == 'Customer':
|
||||
cart_settings = get_shopping_cart_settings()
|
||||
|
||||
if cart_settings.enable_checkout:
|
||||
debtors_account = get_debtors_account(cart_settings)
|
||||
else:
|
||||
debtors_account = ''
|
||||
|
||||
party.update({
|
||||
"customer_name": fullname,
|
||||
"customer_type": "Individual",
|
||||
"customer_group": cart_settings.default_customer_group,
|
||||
"territory": get_root_of("Territory")
|
||||
})
|
||||
|
||||
if debtors_account:
|
||||
party.update({
|
||||
"accounts": [{
|
||||
"company": cart_settings.company,
|
||||
"account": debtors_account
|
||||
}]
|
||||
})
|
||||
else:
|
||||
party.update({
|
||||
"supplier_name": fullname,
|
||||
"supplier_group": "All Supplier Groups",
|
||||
"supplier_type": "Individual"
|
||||
})
|
||||
|
||||
party.flags.ignore_mandatory = True
|
||||
party.insert(ignore_permissions=True)
|
||||
|
||||
contact = frappe.new_doc("Contact")
|
||||
contact.update({
|
||||
"first_name": fullname,
|
||||
"email_id": user
|
||||
})
|
||||
contact.append('links', dict(link_doctype=doctype, link_name=party.name))
|
||||
contact.flags.ignore_mandatory = True
|
||||
contact.insert(ignore_permissions=True)
|
||||
|
||||
return party
|
||||
|
||||
|
||||
def party_exists(doctype, user):
|
||||
contact_name = frappe.db.get_value("Contact", {"email_id": user})
|
||||
|
||||
if contact_name:
|
||||
contact = frappe.get_doc('Contact', contact_name)
|
||||
doctypes = [d.link_doctype for d in contact.links]
|
||||
return doctype in doctypes
|
||||
|
||||
return False
|
||||
|
@ -1233,7 +1233,8 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
"is_return": cint(me.frm.doc.is_return),
|
||||
"update_stock": in_list(['Sales Invoice', 'Purchase Invoice'], me.frm.doc.doctype) ? cint(me.frm.doc.update_stock) : 0,
|
||||
"conversion_factor": me.frm.doc.conversion_factor,
|
||||
"pos_profile": me.frm.doc.doctype == 'Sales Invoice' ? me.frm.doc.pos_profile : ''
|
||||
"pos_profile": me.frm.doc.doctype == 'Sales Invoice' ? me.frm.doc.pos_profile : '',
|
||||
"coupon_code": me.frm.doc.coupon_code
|
||||
};
|
||||
},
|
||||
|
||||
@ -1652,6 +1653,11 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
'item_code': item.item_code,
|
||||
'posting_date': me.frm.doc.posting_date || frappe.datetime.nowdate(),
|
||||
}
|
||||
|
||||
if (doc.is_return) {
|
||||
filters["is_return"] = 1;
|
||||
}
|
||||
|
||||
if (item.warehouse) filters["warehouse"] = item.warehouse;
|
||||
|
||||
return {
|
||||
@ -1742,6 +1748,15 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
frappe.model.set_value(me.frm.doctype + " Item", item.name, "warehouse", me.frm.doc.set_warehouse);
|
||||
});
|
||||
}
|
||||
},
|
||||
coupon_code: function() {
|
||||
var me = this;
|
||||
frappe.run_serially([
|
||||
() => this.frm.doc.ignore_pricing_rule=1,
|
||||
() => me.ignore_pricing_rule(),
|
||||
() => this.frm.doc.ignore_pricing_rule=0,
|
||||
() => me.apply_pricing_rule()
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -5,6 +5,19 @@
|
||||
frappe.provide("erpnext.shopping_cart");
|
||||
var shopping_cart = erpnext.shopping_cart;
|
||||
|
||||
var getParams = function (url) {
|
||||
var params = [];
|
||||
var parser = document.createElement('a');
|
||||
parser.href = url;
|
||||
var query = parser.search.substring(1);
|
||||
var vars = query.split('&');
|
||||
for (var i = 0; i < vars.length; i++) {
|
||||
var pair = vars[i].split('=');
|
||||
params[pair[0]] = decodeURIComponent(pair[1]);
|
||||
}
|
||||
return params;
|
||||
};
|
||||
|
||||
frappe.ready(function() {
|
||||
var full_name = frappe.session && frappe.session.user_fullname;
|
||||
// update user
|
||||
@ -12,7 +25,32 @@ frappe.ready(function() {
|
||||
$('.navbar li[data-label="User"] a')
|
||||
.html('<i class="fa fa-fixed-width fa fa-user"></i> ' + full_name);
|
||||
}
|
||||
// set coupon code and sales partner code
|
||||
|
||||
var url_args = getParams(window.location.href);
|
||||
|
||||
var referral_coupon_code = url_args['cc'];
|
||||
var referral_sales_partner = url_args['sp'];
|
||||
|
||||
var d = new Date();
|
||||
// expires within 30 minutes
|
||||
d.setTime(d.getTime() + (0.02 * 24 * 60 * 60 * 1000));
|
||||
var expires = "expires="+d.toUTCString();
|
||||
if (referral_coupon_code) {
|
||||
document.cookie = "referral_coupon_code=" + referral_coupon_code + ";" + expires + ";path=/";
|
||||
}
|
||||
if (referral_sales_partner) {
|
||||
document.cookie = "referral_sales_partner=" + referral_sales_partner + ";" + expires + ";path=/";
|
||||
}
|
||||
referral_coupon_code=frappe.get_cookie("referral_coupon_code");
|
||||
referral_sales_partner=frappe.get_cookie("referral_sales_partner");
|
||||
|
||||
if (referral_coupon_code && $(".tot_quotation_discount").val()==undefined ) {
|
||||
$(".txtcoupon").val(referral_coupon_code);
|
||||
}
|
||||
if (referral_sales_partner) {
|
||||
$(".txtreferral_sales_partner").val(referral_sales_partner);
|
||||
}
|
||||
// update login
|
||||
shopping_cart.show_shoppingcart_dropdown();
|
||||
shopping_cart.set_cart_count();
|
||||
|
@ -51,3 +51,30 @@
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.website-list .result {
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.result {
|
||||
border-bottom: 1px solid $border-color;
|
||||
}
|
||||
|
||||
.transaction-list-item {
|
||||
padding: 1rem 0;
|
||||
border-top: 1px solid $border-color;
|
||||
position: relative;
|
||||
|
||||
a.transaction-item-link {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-decoration: none;
|
||||
opacity: 0;
|
||||
overflow: hidden;
|
||||
text-indent: -9999px;
|
||||
z-index: 0;
|
||||
}
|
||||
}
|
||||
|
0
erpnext/regional/doctype/datev_settings/__init__.py
Normal file
0
erpnext/regional/doctype/datev_settings/__init__.py
Normal file
@ -0,0 +1,8 @@
|
||||
// Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('DATEV Settings', {
|
||||
// refresh: function(frm) {
|
||||
|
||||
// }
|
||||
});
|
105
erpnext/regional/doctype/datev_settings/datev_settings.json
Normal file
105
erpnext/regional/doctype/datev_settings/datev_settings.json
Normal file
@ -0,0 +1,105 @@
|
||||
{
|
||||
"autoname": "field:client",
|
||||
"creation": "2019-08-13 23:56:34.259906",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"client",
|
||||
"column_break_2",
|
||||
"client_number",
|
||||
"section_break_4",
|
||||
"consultant",
|
||||
"column_break_6",
|
||||
"consultant_number"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "client",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Client",
|
||||
"options": "Company",
|
||||
"reqd": 1,
|
||||
"unique": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "client_number",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Client ID",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "consultant",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Consultant",
|
||||
"options": "Supplier"
|
||||
},
|
||||
{
|
||||
"fieldname": "consultant_number",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Consultant ID",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_2",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_4",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_6",
|
||||
"fieldtype": "Column Break"
|
||||
}
|
||||
],
|
||||
"modified": "2019-08-14 00:03:26.616460",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Regional",
|
||||
"name": "DATEV Settings",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"create": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts User",
|
||||
"share": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
10
erpnext/regional/doctype/datev_settings/datev_settings.py
Normal file
10
erpnext/regional/doctype/datev_settings/datev_settings.py
Normal file
@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
# import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class DATEVSettings(Document):
|
||||
pass
|
@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# import frappe
|
||||
import unittest
|
||||
|
||||
class TestDATEVSettings(unittest.TestCase):
|
||||
pass
|
@ -1,6 +1,6 @@
|
||||
{{ address_line1 }}<br>{% if address_line2 %}{{ address_line2 }}<br>{% endif -%}{{ city }}<br>
|
||||
{% if gst_state %}{{ gst_state }}{% endif -%},
|
||||
{% if gst_state_number %}State Code: {{ gst_state_number }}<br>{% endif -%}
|
||||
{% if gst_state %}{{ gst_state }}{% endif -%}
|
||||
{% if gst_state_number %}, State Code: {{ gst_state_number }}<br>{% endif -%}
|
||||
{% if pincode %}PIN: {{ pincode }}<br>{% endif -%}
|
||||
{{ country }}<br>
|
||||
{% if phone %}Phone: {{ phone }}<br>{% endif -%}
|
||||
|
@ -19,7 +19,7 @@
|
||||
{%- endmacro %}
|
||||
|
||||
{%- macro render_discount_or_margin(item) -%}
|
||||
{%- if item.discount_percentage > 0.0 or item.margin_type %}
|
||||
{%- if (item.discount_percentage and item.discount_percentage > 0.0) or item.margin_type %}
|
||||
<ScontoMaggiorazione>
|
||||
{%- if item.discount_percentage > 0.0 %}
|
||||
<Tipo>SC</Tipo>
|
||||
|
@ -151,8 +151,7 @@ def get_invoice_summary(items, taxes):
|
||||
tax_rate=tax.rate,
|
||||
tax_amount=(reference_row.tax_amount * tax.rate) / 100,
|
||||
net_amount=reference_row.tax_amount,
|
||||
taxable_amount=(reference_row.tax_amount if tax.charge_type == 'On Previous Row Amount'
|
||||
else reference_row.total),
|
||||
taxable_amount=reference_row.tax_amount,
|
||||
item_tax_rate={tax.account_head: tax.rate},
|
||||
charges=True
|
||||
)
|
||||
@ -177,6 +176,10 @@ def get_invoice_summary(items, taxes):
|
||||
summary_data[key]["tax_exemption_reason"] = tax.tax_exemption_reason
|
||||
summary_data[key]["tax_exemption_law"] = tax.tax_exemption_law
|
||||
|
||||
if summary_data.get("0.0") and tax.charge_type in ["On Previous Row Total",
|
||||
"On Previous Row Amount"]:
|
||||
summary_data[key]["taxable_amount"] = tax.total
|
||||
|
||||
if summary_data == {}: #Implies that Zero VAT has not been set on any item.
|
||||
summary_data.setdefault("0.0", {"tax_amount": 0.0, "taxable_amount": tax.total,
|
||||
"tax_exemption_reason": tax.tax_exemption_reason, "tax_exemption_law": tax.tax_exemption_law})
|
||||
|
@ -8,6 +8,7 @@ Provide a report and downloadable CSV according to the German DATEV format.
|
||||
all required columns. Used to import the data into the DATEV Software.
|
||||
"""
|
||||
from __future__ import unicode_literals
|
||||
import datetime
|
||||
import json
|
||||
from six import string_types
|
||||
import frappe
|
||||
@ -17,24 +18,28 @@ import pandas as pd
|
||||
|
||||
def execute(filters=None):
|
||||
"""Entry point for frappe."""
|
||||
validate_filters(filters)
|
||||
validate(filters)
|
||||
result = get_gl_entries(filters, as_dict=0)
|
||||
columns = get_columns()
|
||||
|
||||
return columns, result
|
||||
|
||||
|
||||
def validate_filters(filters):
|
||||
"""Make sure all mandatory filters are present."""
|
||||
def validate(filters):
|
||||
"""Make sure all mandatory filters and settings are present."""
|
||||
if not filters.get('company'):
|
||||
frappe.throw(_('{0} is mandatory').format(_('Company')))
|
||||
frappe.throw(_('<b>Company</b> is a mandatory filter.'))
|
||||
|
||||
if not filters.get('from_date'):
|
||||
frappe.throw(_('{0} is mandatory').format(_('From Date')))
|
||||
frappe.throw(_('<b>From Date</b> is a mandatory filter.'))
|
||||
|
||||
if not filters.get('to_date'):
|
||||
frappe.throw(_('{0} is mandatory').format(_('To Date')))
|
||||
frappe.throw(_('<b>To Date</b> is a mandatory filter.'))
|
||||
|
||||
try:
|
||||
frappe.get_doc('DATEV Settings', filters.get('company'))
|
||||
except frappe.DoesNotExistError:
|
||||
frappe.throw(_('Please create <b>DATEV Settings</b> for Company <b>{}</b>.').format(filters.get('company')))
|
||||
|
||||
def get_columns():
|
||||
"""Return the list of columns that will be shown in query report."""
|
||||
@ -158,13 +163,84 @@ def get_gl_entries(filters, as_dict):
|
||||
return gl_entries
|
||||
|
||||
|
||||
def get_datev_csv(data):
|
||||
def get_datev_csv(data, filters):
|
||||
"""
|
||||
Fill in missing columns and return a CSV in DATEV Format.
|
||||
|
||||
For automatic processing, DATEV requires the first line of the CSV file to
|
||||
hold meta data such as the length of account numbers oder the category of
|
||||
the data.
|
||||
|
||||
Arguments:
|
||||
data -- array of dictionaries
|
||||
filters -- dict
|
||||
"""
|
||||
header = [
|
||||
# A = DATEV format
|
||||
# DTVF = created by DATEV software,
|
||||
# EXTF = created by other software
|
||||
"EXTF",
|
||||
# B = version of the DATEV format
|
||||
# 141 = 1.41,
|
||||
# 510 = 5.10,
|
||||
# 720 = 7.20
|
||||
"510",
|
||||
# C = Data category
|
||||
# 21 = Transaction batch (Buchungsstapel),
|
||||
# 67 = Buchungstextkonstanten,
|
||||
# 16 = Debitors/Creditors,
|
||||
# 20 = Account names (Kontenbeschriftungen)
|
||||
"21",
|
||||
# D = Format name
|
||||
# Buchungsstapel,
|
||||
# Buchungstextkonstanten,
|
||||
# Debitoren/Kreditoren,
|
||||
# Kontenbeschriftungen
|
||||
"Buchungsstapel",
|
||||
# E = Format version (regarding format name)
|
||||
"",
|
||||
# F = Generated on
|
||||
datetime.datetime.now().strftime("%Y%m%d"),
|
||||
# G = Imported on -- stays empty
|
||||
"",
|
||||
# H = Origin (SV = other (?), RE = KARE)
|
||||
"SV",
|
||||
# I = Exported by
|
||||
frappe.session.user,
|
||||
# J = Imported by -- stays empty
|
||||
"",
|
||||
# K = Tax consultant number (Beraternummer)
|
||||
frappe.get_value("DATEV Settings", filters.get("company"), "consultant_number") or "",
|
||||
"",
|
||||
# L = Tax client number (Mandantennummer)
|
||||
frappe.get_value("DATEV Settings", filters.get("company"), "client_number") or "",
|
||||
"",
|
||||
# M = Start of the fiscal year (Wirtschaftsjahresbeginn)
|
||||
frappe.utils.formatdate(frappe.defaults.get_user_default("year_start_date"), "yyyyMMdd"),
|
||||
# N = Length of account numbers (Sachkontenlänge)
|
||||
"4",
|
||||
# O = Transaction batch start date (YYYYMMDD)
|
||||
frappe.utils.formatdate(filters.get('from_date'), "yyyyMMdd"),
|
||||
# P = Transaction batch end date (YYYYMMDD)
|
||||
frappe.utils.formatdate(filters.get('to_date'), "yyyyMMdd"),
|
||||
# Q = Description (for example, "January - February 2019 Transactions")
|
||||
"{} - {} Buchungsstapel".format(
|
||||
frappe.utils.formatdate(filters.get('from_date'), "MMMM yyyy"),
|
||||
frappe.utils.formatdate(filters.get('to_date'), "MMMM yyyy")
|
||||
),
|
||||
# R = Diktatkürzel
|
||||
"",
|
||||
# S = Buchungstyp
|
||||
# 1 = Transaction batch (Buchungsstapel),
|
||||
# 2 = Annual financial statement (Jahresabschluss)
|
||||
"1",
|
||||
# T = Rechnungslegungszweck
|
||||
"",
|
||||
# U = Festschreibung
|
||||
"",
|
||||
# V = Kontoführungs-Währungskennzeichen des Geldkontos
|
||||
frappe.get_value("Company", filters.get("company"), "default_currency")
|
||||
]
|
||||
columns = [
|
||||
# All possible columns must tbe listed here, because DATEV requires them to
|
||||
# be present in the CSV.
|
||||
@ -324,9 +400,10 @@ def get_datev_csv(data):
|
||||
data_df = pd.DataFrame.from_records(data)
|
||||
|
||||
result = empty_df.append(data_df)
|
||||
result["Belegdatum"] = pd.to_datetime(result["Belegdatum"])
|
||||
result['Belegdatum'] = pd.to_datetime(result['Belegdatum'])
|
||||
|
||||
return result.to_csv(
|
||||
header = ';'.join(header).encode('latin_1')
|
||||
data = result.to_csv(
|
||||
sep=b';',
|
||||
# European decimal seperator
|
||||
decimal=',',
|
||||
@ -342,6 +419,7 @@ def get_datev_csv(data):
|
||||
columns=columns
|
||||
)
|
||||
|
||||
return header + b'\r\n' + data
|
||||
|
||||
@frappe.whitelist()
|
||||
def download_datev_csv(filters=None):
|
||||
@ -359,15 +437,9 @@ def download_datev_csv(filters=None):
|
||||
if isinstance(filters, string_types):
|
||||
filters = json.loads(filters)
|
||||
|
||||
validate_filters(filters)
|
||||
validate(filters)
|
||||
data = get_gl_entries(filters, as_dict=1)
|
||||
|
||||
filename = 'DATEV_Buchungsstapel_{}-{}_bis_{}'.format(
|
||||
filters.get('company'),
|
||||
filters.get('from_date'),
|
||||
filters.get('to_date')
|
||||
)
|
||||
|
||||
frappe.response['result'] = get_datev_csv(data)
|
||||
frappe.response['doctype'] = filename
|
||||
frappe.response['result'] = get_datev_csv(data, filters)
|
||||
frappe.response['doctype'] = 'EXTF_Buchungsstapel'
|
||||
frappe.response['type'] = 'csv'
|
||||
|
@ -8,7 +8,7 @@ import unittest
|
||||
|
||||
from erpnext.accounts.party import get_due_date
|
||||
from frappe.test_runner import make_test_records
|
||||
from erpnext.exceptions import PartyFrozen
|
||||
from erpnext.exceptions import PartyFrozen, PartyDisabled
|
||||
from frappe.utils import flt
|
||||
from erpnext.selling.doctype.customer.customer import get_credit_limit, get_customer_outstanding
|
||||
from erpnext.tests.utils import create_test_contact_and_address
|
||||
@ -178,7 +178,7 @@ class TestCustomer(unittest.TestCase):
|
||||
|
||||
so = make_sales_order(do_not_save=True)
|
||||
|
||||
self.assertRaises(frappe.ValidationError, so.save)
|
||||
self.assertRaises(PartyDisabled, so.save)
|
||||
|
||||
frappe.db.set_value("Customer", "_Test Customer", "disabled", 0)
|
||||
|
||||
|
@ -1904,7 +1904,7 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Additional Discount",
|
||||
"label": "Additional Discount and Coupon Code",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
@ -1920,6 +1920,74 @@
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "coupon_code",
|
||||
"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": "Coupon Code",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Coupon Code",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "referral_sales_partner",
|
||||
"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": "Referral Sales Partner",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Sales Partner",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
@ -3263,7 +3331,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 1,
|
||||
"menu_index": 0,
|
||||
"modified": "2019-06-26 01:00:21.545591",
|
||||
"modified": "2019-10-14 01:00:21.545591",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Quotation",
|
||||
|
@ -142,6 +142,9 @@ def _make_sales_order(source_name, target_doc=None, ignore_permissions=False):
|
||||
if customer:
|
||||
target.customer = customer.name
|
||||
target.customer_name = customer.customer_name
|
||||
if source.referral_sales_partner:
|
||||
target.sales_partner=source.referral_sales_partner
|
||||
target.commission_rate=frappe.get_value('Sales Partner', source.referral_sales_partner, 'commission_rate')
|
||||
target.ignore_pricing_rule = 1
|
||||
target.flags.ignore_permissions = ignore_permissions
|
||||
target.run_method("set_missing_values")
|
||||
|
@ -136,7 +136,8 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
|
||||
if(doc.status !== 'Closed') {
|
||||
if(doc.status !== 'On Hold') {
|
||||
|
||||
allow_delivery = this.frm.doc.items.some(item => item.delivered_by_supplier === 0 && item.qty > flt(item.delivered_qty))
|
||||
allow_delivery = this.frm.doc.items.some(item => item.delivered_by_supplier === 0 && item.qty > flt(item.delivered_qty))
|
||||
&& !this.frm.doc.skip_delivery_note
|
||||
|
||||
if (this.frm.has_perm("submit")) {
|
||||
if(flt(doc.per_delivered, 6) < 100 || flt(doc.per_billed) < 100) {
|
||||
@ -341,7 +342,7 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
|
||||
},
|
||||
|
||||
order_type: function() {
|
||||
this.frm.fields_dict.items.grid.toggle_reqd("delivery_date", this.frm.doc.order_type == "Sales");
|
||||
this.toggle_delivery_date();
|
||||
},
|
||||
|
||||
tc_name: function() {
|
||||
@ -355,6 +356,15 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
|
||||
})
|
||||
},
|
||||
|
||||
skip_delivery_note: function() {
|
||||
this.toggle_delivery_date();
|
||||
},
|
||||
|
||||
toggle_delivery_date: function() {
|
||||
this.frm.fields_dict.items.grid.toggle_reqd("delivery_date",
|
||||
(this.frm.doc.order_type == "Sales" && !this.frm.doc.skip_delivery_note));
|
||||
},
|
||||
|
||||
make_raw_material_request: function() {
|
||||
var me = this;
|
||||
this.frm.call({
|
||||
|
@ -14,6 +14,7 @@
|
||||
"customer",
|
||||
"customer_name",
|
||||
"order_type",
|
||||
"skip_delivery_note",
|
||||
"column_break1",
|
||||
"amended_from",
|
||||
"company",
|
||||
@ -78,6 +79,7 @@
|
||||
"loyalty_points",
|
||||
"loyalty_amount",
|
||||
"section_break_48",
|
||||
"coupon_code",
|
||||
"apply_discount_on",
|
||||
"base_discount_amount",
|
||||
"column_break_50",
|
||||
@ -252,6 +254,7 @@
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:!doc.skip_delivery_note",
|
||||
"fieldname": "delivery_date",
|
||||
"fieldtype": "Date",
|
||||
"in_list_view": 1,
|
||||
@ -676,7 +679,13 @@
|
||||
"collapsible_depends_on": "discount_amount",
|
||||
"fieldname": "section_break_48",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Additional Discount"
|
||||
"label": "Additional Discount and Coupon Code"
|
||||
},
|
||||
{
|
||||
"fieldname": "coupon_code",
|
||||
"fieldtype": "Link",
|
||||
"label": "Coupon Code",
|
||||
"options": "Coupon Code"
|
||||
},
|
||||
{
|
||||
"default": "Grand Total",
|
||||
@ -941,7 +950,7 @@
|
||||
"collapsible": 1,
|
||||
"fieldname": "printing_details",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Printing Details"
|
||||
"label": "Print Settings"
|
||||
},
|
||||
{
|
||||
"fieldname": "language",
|
||||
@ -1023,7 +1032,7 @@
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:!doc.__islocal",
|
||||
"depends_on": "eval:!doc.__islocal && !doc.skip_delivery_note_creation",
|
||||
"description": "% of materials delivered against this Sales Order",
|
||||
"fieldname": "per_delivered",
|
||||
"fieldtype": "Percent",
|
||||
@ -1120,7 +1129,7 @@
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "sales_team",
|
||||
"fieldtype": "Table",
|
||||
"label": "Sales Team1",
|
||||
"label": "Sales Team",
|
||||
"oldfieldname": "sales_team",
|
||||
"oldfieldtype": "Table",
|
||||
"options": "Sales Team",
|
||||
@ -1171,12 +1180,20 @@
|
||||
"fieldtype": "Data",
|
||||
"label": "Phone",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "skip_delivery_note",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 1,
|
||||
"label": "Skip Delivery Note",
|
||||
"print_hide": 1
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-file-text",
|
||||
"idx": 105,
|
||||
"is_submittable": 1,
|
||||
"modified": "2019-09-12 02:13:56.308839",
|
||||
"modified": "2019-10-22 14:26:42.767189",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Sales Order",
|
||||
|
@ -46,6 +46,10 @@ class SalesOrder(SellingController):
|
||||
self.validate_serial_no_based_delivery()
|
||||
validate_inter_company_party(self.doctype, self.customer, self.company, self.inter_company_order_reference)
|
||||
|
||||
if self.coupon_code:
|
||||
from erpnext.accounts.doctype.pricing_rule.utils import validate_coupon_code
|
||||
validate_coupon_code(self.coupon_code)
|
||||
|
||||
from erpnext.stock.doctype.packed_item.packed_item import make_packing_list
|
||||
make_packing_list(self)
|
||||
|
||||
@ -57,13 +61,13 @@ class SalesOrder(SellingController):
|
||||
|
||||
def validate_po(self):
|
||||
# validate p.o date v/s delivery date
|
||||
if self.po_date:
|
||||
if self.po_date and not self.skip_delivery_note:
|
||||
for d in self.get("items"):
|
||||
if d.delivery_date and getdate(self.po_date) > getdate(d.delivery_date):
|
||||
frappe.throw(_("Row #{0}: Expected Delivery Date cannot be before Purchase Order Date")
|
||||
.format(d.idx))
|
||||
|
||||
if self.po_no and self.customer:
|
||||
if self.po_no and self.customer and not self.skip_delivery_note:
|
||||
so = frappe.db.sql("select name from `tabSales Order` \
|
||||
where ifnull(po_no, '') = %s and name != %s and docstatus < 2\
|
||||
and customer = %s", (self.po_no, self.name, self.customer))
|
||||
@ -100,7 +104,7 @@ class SalesOrder(SellingController):
|
||||
super(SalesOrder, self).validate_order_type()
|
||||
|
||||
def validate_delivery_date(self):
|
||||
if self.order_type == 'Sales':
|
||||
if self.order_type == 'Sales' and not self.skip_delivery_note:
|
||||
delivery_date_list = [d.delivery_date for d in self.get("items") if d.delivery_date]
|
||||
max_delivery_date = max(delivery_date_list) if delivery_date_list else None
|
||||
if not self.delivery_date:
|
||||
@ -177,6 +181,9 @@ class SalesOrder(SellingController):
|
||||
self.update_blanket_order()
|
||||
|
||||
update_linked_doc(self.doctype, self.name, self.inter_company_order_reference)
|
||||
if self.coupon_code:
|
||||
from erpnext.accounts.doctype.pricing_rule.utils import update_coupon_code_count
|
||||
update_coupon_code_count(self.coupon_code,'used')
|
||||
|
||||
def on_cancel(self):
|
||||
super(SalesOrder, self).on_cancel()
|
||||
@ -195,7 +202,10 @@ class SalesOrder(SellingController):
|
||||
self.update_blanket_order()
|
||||
|
||||
unlink_inter_company_doc(self.doctype, self.name, self.inter_company_order_reference)
|
||||
|
||||
if self.coupon_code:
|
||||
from erpnext.accounts.doctype.pricing_rule.utils import update_coupon_code_count
|
||||
update_coupon_code_count(self.coupon_code,'cancelled')
|
||||
|
||||
def update_project(self):
|
||||
if frappe.db.get_single_value('Selling Settings', 'sales_update_frequency') != "Each Transaction":
|
||||
return
|
||||
@ -760,6 +770,7 @@ def get_events(start, end, filters=None):
|
||||
from
|
||||
`tabSales Order`, `tabSales Order Item`
|
||||
where `tabSales Order`.name = `tabSales Order Item`.parent
|
||||
and `tabSales Order`.skip_delivery_note = 0
|
||||
and (ifnull(`tabSales Order Item`.delivery_date, '0000-00-00')!= '0000-00-00') \
|
||||
and (`tabSales Order Item`.delivery_date between %(start)s and %(end)s)
|
||||
and `tabSales Order`.docstatus < 2
|
||||
|
@ -1,58 +1,41 @@
|
||||
frappe.listview_settings['Sales Order'] = {
|
||||
add_fields: ["base_grand_total", "customer_name", "currency", "delivery_date",
|
||||
"per_delivered", "per_billed", "status", "order_type", "name"],
|
||||
"per_delivered", "per_billed", "status", "order_type", "name", "skip_delivery_note"],
|
||||
get_indicator: function (doc) {
|
||||
if (doc.status === "Closed") {
|
||||
// Closed
|
||||
return [__("Closed"), "green", "status,=,Closed"];
|
||||
|
||||
} else if (doc.status === "On Hold") {
|
||||
// on hold
|
||||
return [__("On Hold"), "orange", "status,=,On Hold"];
|
||||
} else if (doc.order_type !== "Maintenance"
|
||||
&& flt(doc.per_delivered, 6) < 100 && frappe.datetime.get_diff(doc.delivery_date) < 0) {
|
||||
} else if (doc.status === "Completed") {
|
||||
return [__("Completed"), "green", "status,=,Completed"];
|
||||
} else if (!doc.skip_delivery_note && flt(doc.per_delivered, 6) < 100) {
|
||||
if (frappe.datetime.get_diff(doc.delivery_date) < 0) {
|
||||
// not delivered & overdue
|
||||
return [__("Overdue"), "red", "per_delivered,<,100|delivery_date,<,Today|status,!=,Closed"];
|
||||
|
||||
} else if (doc.order_type !== "Maintenance"
|
||||
&& flt(doc.per_delivered, 6) < 100 && doc.status !== "Closed") {
|
||||
// not delivered
|
||||
|
||||
if (flt(doc.grand_total) === 0) {
|
||||
return [__("Overdue"), "red",
|
||||
"per_delivered,<,100|delivery_date,<,Today|status,!=,Closed"];
|
||||
} else if (flt(doc.grand_total) === 0) {
|
||||
// not delivered (zero-amount order)
|
||||
|
||||
return [__("To Deliver"), "orange",
|
||||
"per_delivered,<,100|grand_total,=,0|status,!=,Closed"];
|
||||
} else if (flt(doc.per_billed, 6) < 100) {
|
||||
// not delivered & not billed
|
||||
|
||||
return [__("To Deliver and Bill"), "orange",
|
||||
"per_delivered,<,100|per_billed,<,100|status,!=,Closed"];
|
||||
} else {
|
||||
// not billed
|
||||
|
||||
return [__("To Deliver"), "orange",
|
||||
"per_delivered,<,100|per_billed,=,100|status,!=,Closed"];
|
||||
}
|
||||
|
||||
} else if ((flt(doc.per_delivered, 6) === 100)
|
||||
&& flt(doc.grand_total) !== 0 && flt(doc.per_billed, 6) < 100 && doc.status !== "Closed") {
|
||||
} else if ((flt(doc.per_delivered, 6) === 100) && flt(doc.grand_total) !== 0
|
||||
&& flt(doc.per_billed, 6) < 100) {
|
||||
// to bill
|
||||
|
||||
return [__("To Bill"), "orange", "per_delivered,=,100|per_billed,<,100|status,!=,Closed"];
|
||||
|
||||
} else if ((flt(doc.per_delivered, 6) === 100)
|
||||
&& (flt(doc.grand_total) === 0 || flt(doc.per_billed, 6) == 100) && doc.status !== "Closed") {
|
||||
return [__("Completed"), "green", "per_delivered,=,100|per_billed,=,100|status,!=,Closed"];
|
||||
|
||||
}else if (doc.order_type === "Maintenance" && flt(doc.per_delivered, 6) < 100 && doc.status !== "Closed"){
|
||||
|
||||
if(flt(doc.per_billed, 6) < 100 ){
|
||||
return [__("To Deliver and Bill"), "orange", "per_delivered,=,100|per_billed,<,100|status,!=,Closed"];
|
||||
}else if(flt(doc.per_billed, 6) === 100){
|
||||
return [__("To Deliver"), "orange", "per_delivered,=,100|per_billed,=,100|status,!=,Closed"];
|
||||
}
|
||||
return [__("To Bill"), "orange",
|
||||
"per_delivered,=,100|per_billed,<,100|status,!=,Closed"];
|
||||
} else if (doc.skip_delivery_note && flt(doc.per_billed, 6) < 100){
|
||||
return [__("To Bill"), "orange", "per_billed,<,100|status,!=,Closed"];
|
||||
}
|
||||
|
||||
},
|
||||
onload: function(listview) {
|
||||
var method = "erpnext.selling.doctype.sales_order.sales_order.close_or_unclose_sales_orders";
|
||||
|
@ -149,6 +149,7 @@
|
||||
},
|
||||
{
|
||||
"columns": 2,
|
||||
"depends_on": "eval: !parent.skip_delivery_note",
|
||||
"fieldname": "delivery_date",
|
||||
"fieldtype": "Date",
|
||||
"in_list_view": 1,
|
||||
@ -693,6 +694,7 @@
|
||||
"description": "For Production",
|
||||
"fieldname": "produced_qty",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 1,
|
||||
"label": "Produced Quantity",
|
||||
"oldfieldname": "produced_qty",
|
||||
"oldfieldtype": "Currency",
|
||||
@ -743,7 +745,7 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2019-09-13 12:18:54.903107",
|
||||
"modified": "2019-10-10 08:46:26.244823",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Sales Order Item",
|
||||
|
@ -80,10 +80,14 @@ frappe.query_reports["Sales Analytics"] = {
|
||||
|
||||
var tree_type = frappe.query_report.filters[0].value;
|
||||
|
||||
if(tree_type == "Customer" || tree_type == "Item") {
|
||||
if(tree_type == "Customer") {
|
||||
row_values = data.slice(4,length-1).map(function (column) {
|
||||
return column.content;
|
||||
})
|
||||
} else if (tree_type == "Item") {
|
||||
row_values = data.slice(5,length-1).map(function (column) {
|
||||
return column.content;
|
||||
})
|
||||
}
|
||||
else {
|
||||
row_values = data.slice(3,length-1).map(function (column) {
|
||||
|
@ -136,7 +136,7 @@ class Analytics(object):
|
||||
if self.filters["value_quantity"] == 'Value':
|
||||
value_field = 'base_amount'
|
||||
else:
|
||||
value_field = 'qty'
|
||||
value_field = 'stock_qty'
|
||||
|
||||
self.entries = frappe.db.sql("""
|
||||
select i.item_code as entity, i.item_name as entity_name, i.stock_uom, i.{value_field} as value_field, s.{date_field}
|
||||
@ -338,8 +338,10 @@ class Analytics(object):
|
||||
def get_chart_data(self):
|
||||
length = len(self.columns)
|
||||
|
||||
if self.filters.tree_type in ["Customer", "Supplier", "Item"]:
|
||||
if self.filters.tree_type in ["Customer", "Supplier"]:
|
||||
labels = [d.get("label") for d in self.columns[2:length - 1]]
|
||||
elif self.filters.tree_type == "Item":
|
||||
labels = [d.get("label") for d in self.columns[3:length - 1]]
|
||||
else:
|
||||
labels = [d.get("label") for d in self.columns[1:length - 1]]
|
||||
self.chart = {
|
||||
|
@ -204,7 +204,7 @@ class Company(NestedSet):
|
||||
})
|
||||
|
||||
for default_account in default_accounts:
|
||||
if self.is_new() or frappe.flags.in_test:
|
||||
if self.is_new() or frappe.flags.in_test or frappe.flags.in_demo:
|
||||
self._set_default_account(default_account, default_accounts.get(default_account))
|
||||
|
||||
if not self.default_income_account:
|
||||
|
@ -24,5 +24,11 @@ frappe.ui.form.on('Sales Partner', {
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
referral_code:function(frm){
|
||||
if (frm.doc.referral_code) {
|
||||
frm.doc.referral_code=frm.doc.referral_code.toUpperCase();
|
||||
frm.refresh_field('referral_code');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -510,6 +510,73 @@
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "column_break_16",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"description": "To Track inbound purchase",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "referral_code",
|
||||
"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": "Referral Code",
|
||||
"length": 8,
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
@ -779,7 +846,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2019-03-21 16:26:45.447265",
|
||||
"modified": "2019-10-14 16:26:45.447265",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Setup",
|
||||
"name": "Sales Partner",
|
||||
|
@ -65,7 +65,7 @@ def install(country=None):
|
||||
{'doctype': 'Leave Type', 'leave_type_name': _('Casual Leave'), 'name': _('Casual Leave'),
|
||||
'allow_encashment': 1, 'is_carry_forward': 1, 'max_continuous_days_allowed': '3', 'include_holiday': 1},
|
||||
{'doctype': 'Leave Type', 'leave_type_name': _('Compensatory Off'), 'name': _('Compensatory Off'),
|
||||
'allow_encashment': 0, 'is_carry_forward': 0, 'include_holiday': 1},
|
||||
'allow_encashment': 0, 'is_carry_forward': 0, 'include_holiday': 1, 'is_compensatory':1 },
|
||||
{'doctype': 'Leave Type', 'leave_type_name': _('Sick Leave'), 'name': _('Sick Leave'),
|
||||
'allow_encashment': 0, 'is_carry_forward': 0, 'include_holiday': 1},
|
||||
{'doctype': 'Leave Type', 'leave_type_name': _('Privilege Leave'), 'name': _('Privilege Leave'),
|
||||
|
@ -65,7 +65,12 @@ def get_setup_stages(args=None):
|
||||
'fn': stage_four,
|
||||
'args': args,
|
||||
'fail_msg': _("Failed to create website")
|
||||
}
|
||||
},
|
||||
{
|
||||
'fn': set_active_domains,
|
||||
'args': args,
|
||||
'fail_msg': _("Failed to add Domain")
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -128,3 +133,7 @@ def setup_complete(args=None):
|
||||
setup_defaults(args)
|
||||
stage_four(args)
|
||||
fin(args)
|
||||
|
||||
def set_active_domains(args):
|
||||
domain_settings = frappe.get_single('Domain Settings')
|
||||
domain_settings.set_active_domains(args.get('domains'))
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user