Merge branch 'develop' into dev-work-order-bugs

This commit is contained in:
Rohan 2019-10-29 11:25:53 +05:30 committed by GitHub
commit 379f38e1cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 108 additions and 109 deletions

View File

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

View File

@ -308,7 +308,7 @@ frappe.ui.form.on('Payment Entry', {
() => { () => {
frm.set_party_account_based_on_party = false; frm.set_party_account_based_on_party = false;
if (r.message.bank_account) { if (r.message.bank_account) {
frm.set_value("bank_account", r.message.bank_account); frm.set_value("party_bank_account", r.message.bank_account);
} }
} }
]); ]);

View File

@ -69,7 +69,7 @@ def get_columns(filters):
for year in fiscal_year: for year in fiscal_year:
for from_date, to_date in get_period_date_ranges(filters["period"], year[0]): for from_date, to_date in get_period_date_ranges(filters["period"], year[0]):
if filters["period"] == "Yearly": if filters["period"] == "Yearly":
labels = [_("Budget") + " " + str(year[0]), _("Actual ") + " " + str(year[0]), _("Varaiance ") + " " + str(year[0])] labels = [_("Budget") + " " + str(year[0]), _("Actual ") + " " + str(year[0]), _("Variance ") + " " + str(year[0])]
for label in labels: for label in labels:
columns.append(label+":Float:150") columns.append(label+":Float:150")
else: else:

View File

@ -18,7 +18,7 @@ def get_data():
"onboard_present": 1 "onboard_present": 1
}, },
{ {
"module_name": "Accounting", "module_name": "Accounts",
"category": "Modules", "category": "Modules",
"label": _("Accounting"), "label": _("Accounting"),
"color": "#3498db", "color": "#3498db",

View File

@ -127,7 +127,11 @@ def get_data():
"name": "Shipping Rule", "name": "Shipping Rule",
"description": _("Rules for adding shipping costs."), "description": _("Rules for adding shipping costs."),
}, },
{
"type": "doctype",
"name": "Coupon Code",
"description": _("Define coupon codes."),
}
] ]
}, },
{ {

View File

@ -280,8 +280,13 @@ def get_batch_no(doctype, txt, searchfield, start, page_len, filters):
"page_len": page_len "page_len": page_len
} }
having_clause = "having sum(sle.actual_qty) > 0"
if filters.get("is_return"):
having_clause = ""
if args.get('warehouse'): 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) 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 from `tabStock Ledger Entry` sle
INNER JOIN `tabBatch` batch on sle.batch_no = batch.name INNER JOIN `tabBatch` batch on sle.batch_no = batch.name
where where
@ -291,11 +296,15 @@ def get_batch_no(doctype, txt, searchfield, start, page_len, filters):
and (sle.batch_no like %(txt)s and (sle.batch_no like %(txt)s
or batch.manufacturing_date like %(txt)s) or batch.manufacturing_date like %(txt)s)
and batch.docstatus < 2 and batch.docstatus < 2
{0} {cond}
{match_conditions} {match_conditions}
group by batch_no having sum(sle.actual_qty) > 0 group by batch_no {having_clause}
order by batch.expiry_date, sle.batch_no desc order by batch.expiry_date, sle.batch_no desc
limit %(start)s, %(page_len)s""".format(cond, match_conditions=get_match_cond(doctype)), args) limit %(start)s, %(page_len)s""".format(
cond=cond,
match_conditions=get_match_cond(doctype),
having_clause = having_clause
), args)
return batch_nos return batch_nos
else: else:

View File

@ -10,13 +10,14 @@ from erpnext.demo.domains import data
from frappe import _ from frappe import _
def setup(domain): def setup(domain):
frappe.flags.in_demo = 1
complete_setup(domain) complete_setup(domain)
setup_demo_page() setup_demo_page()
setup_fiscal_year() setup_fiscal_year()
setup_holiday_list() setup_holiday_list()
setup_user() setup_user()
setup_employee() setup_employee()
setup_user_roles() setup_user_roles(domain)
setup_role_permissions() setup_role_permissions()
setup_custom_field_for_domain() setup_custom_field_for_domain()
@ -183,14 +184,20 @@ def setup_salary_structure(employees, salary_slip_based_on_timesheet=0):
return ss return ss
def setup_user_roles(): def setup_user_roles(domain):
user = frappe.get_doc('User', 'demo@erpnext.com') user = frappe.get_doc('User', 'demo@erpnext.com')
user.add_roles('HR User', 'HR Manager', 'Accounts User', 'Accounts Manager', user.add_roles('HR User', 'HR Manager', 'Accounts User', 'Accounts Manager',
'Stock User', 'Stock Manager', 'Sales User', 'Sales Manager', 'Purchase User', 'Stock User', 'Stock Manager', 'Sales User', 'Sales Manager', 'Purchase User',
'Purchase Manager', 'Projects User', 'Manufacturing User', 'Manufacturing Manager', 'Purchase Manager', 'Projects User', 'Manufacturing User', 'Manufacturing Manager',
'Support Team', 'Academics User', 'Physician', 'Healthcare Administrator', 'Laboratory User', 'Support Team')
if domain == "Healthcare":
user.add_roles('Physician', 'Healthcare Administrator', 'Laboratory User',
'Nursing User', 'Patient') 'Nursing User', 'Patient')
if domain == "Education":
user.add_roles('Academics User')
if not frappe.db.get_global('demo_hr_user'): if not frappe.db.get_global('demo_hr_user'):
user = frappe.get_doc('User', 'CaitlinSnow@example.com') user = frappe.get_doc('User', 'CaitlinSnow@example.com')
user.add_roles('HR User', 'HR Manager', 'Accounts User') user.add_roles('HR User', 'HR Manager', 'Accounts User')
@ -219,7 +226,7 @@ def setup_user_roles():
if not frappe.db.get_global('demo_manufacturing_user'): if not frappe.db.get_global('demo_manufacturing_user'):
user = frappe.get_doc('User', 'NeptuniaAquaria@example.com') 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') update_employee_department(user.name, 'Production')
frappe.db.set_global('demo_manufacturing_user', user.name) frappe.db.set_global('demo_manufacturing_user', user.name)
@ -241,6 +248,7 @@ def setup_user_roles():
update_employee_department(user.name, 'Management') update_employee_department(user.name, 'Management')
frappe.db.set_global('demo_projects_user', user.name) frappe.db.set_global('demo_projects_user', user.name)
if domain == "Education":
if not frappe.db.get_global('demo_education_user'): if not frappe.db.get_global('demo_education_user'):
user = frappe.get_doc('User', 'ArthurCurry@example.com') user = frappe.get_doc('User', 'ArthurCurry@example.com')
user.add_roles('Academics User') user.add_roles('Academics User')

View File

@ -73,14 +73,16 @@ def work():
make_pos_invoice() make_pos_invoice()
def make_payment_entries(ref_doctype, report): 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, outstanding_invoices = frappe.get_all(ref_doctype, fields=["name"],
"company": erpnext.get_default_company() filters={
})["result"] if r[2]==ref_doctype])) "company": erpnext.get_default_company(),
"outstanding_amount": (">", 0.0)
})
# make Payment Entry # make Payment Entry
for inv in outstanding_invoices[:random.randint(1, 2)]: 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.posting_date = frappe.flags.current_date
pe.reference_no = random_string(6) pe.reference_no = random_string(6)
pe.reference_date = frappe.flags.current_date pe.reference_date = frappe.flags.current_date
@ -91,7 +93,7 @@ def make_payment_entries(ref_doctype, report):
# make payment via JV # make payment via JV
for inv in outstanding_invoices[:1]: 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.posting_date = frappe.flags.current_date
jv.cheque_no = random_string(6) jv.cheque_no = random_string(6)
jv.cheque_date = frappe.flags.current_date jv.cheque_date = frappe.flags.current_date

View File

@ -39,61 +39,4 @@ def make_project(current_date):
"doctype": "Project", "doctype": "Project",
"project_name": "New Product Development " + current_date.strftime("%Y-%m-%d"), "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() project.insert()

View File

@ -66,7 +66,7 @@ def make_opportunity(domain):
b = frappe.get_doc({ b = frappe.get_doc({
"doctype": "Opportunity", "doctype": "Opportunity",
"opportunity_from": "Customer", "opportunity_from": "Customer",
"customer": get_random("Customer"), "party_name": frappe.get_value("Customer", get_random("Customer"), 'name'),
"opportunity_type": "Sales", "opportunity_type": "Sales",
"with_items": 1, "with_items": 1,
"transaction_date": frappe.flags.current_date, "transaction_date": frappe.flags.current_date,

View File

@ -12,6 +12,7 @@ frappe.ui.form.on('Blanket Order', {
}, },
refresh: function(frm) { refresh: function(frm) {
erpnext.hide_company();
if (frm.doc.customer && frm.doc.docstatus === 1) { if (frm.doc.customer && frm.doc.docstatus === 1) {
frm.add_custom_button(__('View Orders'), function() { frm.add_custom_button(__('View Orders'), function() {
frappe.set_route('List', 'Sales Order', {blanket_order: frm.doc.name}); 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) { set_tc_name_filter: function(frm) {
if (frm.doc.blanket_order_type === 'Selling') { 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() { frm.set_query("tc_name", function() {
return { filters: { selling: 1 } }; return { filters: { selling: 1 } };
}); });
} }
if (frm.doc.blanket_order_type === 'Purchasing') { 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() { frm.set_query("tc_name", function() {
return { filters: { buying: 1 } }; return { filters: { buying: 1 } };
}); });

View File

@ -88,7 +88,8 @@
"fieldname": "company", "fieldname": "company",
"fieldtype": "Link", "fieldtype": "Link",
"label": "Company", "label": "Company",
"options": "Company" "options": "Company",
"reqd": 1
}, },
{ {
"fieldname": "section_break_12", "fieldname": "section_break_12",
@ -128,7 +129,7 @@
} }
], ],
"is_submittable": 1, "is_submittable": 1,
"modified": "2019-06-19 11:59:09.279607", "modified": "2019-10-16 13:38:32.302316",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Manufacturing", "module": "Manufacturing",
"name": "Blanket Order", "name": "Blanket Order",

View File

@ -4,13 +4,21 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import frappe 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.document import Document
from frappe.model.mapper import get_mapped_doc from frappe.model.mapper import get_mapped_doc
from erpnext.stock.doctype.item.item import get_item_defaults from erpnext.stock.doctype.item.item import get_item_defaults
class BlanketOrder(Document): 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): def update_ordered_qty(self):
ref_doctype = "Sales Order" if self.blanket_order_type == "Selling" else "Purchase Order" ref_doctype = "Sales Order" if self.blanket_order_type == "Selling" else "Purchase Order"
item_ordered_qty = frappe._dict(frappe.db.sql(""" item_ordered_qty = frappe._dict(frappe.db.sql("""

View File

@ -640,3 +640,4 @@ erpnext.patches.v12_0.create_default_energy_point_rules
erpnext.patches.v12_0.set_produced_qty_field_in_sales_order_for_work_order erpnext.patches.v12_0.set_produced_qty_field_in_sales_order_for_work_order
erpnext.patches.v12_0.generate_leave_ledger_entries erpnext.patches.v12_0.generate_leave_ledger_entries
erpnext.patches.v12_0.set_default_shopify_app_type erpnext.patches.v12_0.set_default_shopify_app_type
erpnext.patches.v12_0.replace_accounting_with_accounts_in_home_settings

View File

@ -4,7 +4,7 @@ from frappe.model.utils.rename_field import rename_field
def execute(): def execute():
frappe.reload_doc('desk', 'doctype', 'auto_repeat') frappe.reload_doc('automation', 'doctype', 'auto_repeat')
doctypes_to_rename = { doctypes_to_rename = {
'accounts': ['Journal Entry', 'Payment Entry', 'Purchase Invoice', 'Sales Invoice'], 'accounts': ['Journal Entry', 'Payment Entry', 'Purchase Invoice', 'Sales Invoice'],

View File

@ -0,0 +1,5 @@
import frappe
def execute():
frappe.db.sql("""UPDATE `tabUser` SET `home_settings` = REPLACE(`home_settings`, 'Accounting', 'Accounts')""")
frappe.cache().delete_key('home_settings')

View File

@ -1653,6 +1653,11 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
'item_code': item.item_code, 'item_code': item.item_code,
'posting_date': me.frm.doc.posting_date || frappe.datetime.nowdate(), '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; if (item.warehouse) filters["warehouse"] = item.warehouse;
return { return {

View File

@ -661,12 +661,15 @@ def make_sales_invoice(source_name, target_doc=None, ignore_permissions=False):
if source_parent.project: if source_parent.project:
target.cost_center = frappe.db.get_value("Project", source_parent.project, "cost_center") target.cost_center = frappe.db.get_value("Project", source_parent.project, "cost_center")
if not target.cost_center and target.item_code: if target.item_code:
item = get_item_defaults(target.item_code, source_parent.company) item = get_item_defaults(target.item_code, source_parent.company)
item_group = get_item_group_defaults(target.item_code, source_parent.company) item_group = get_item_group_defaults(target.item_code, source_parent.company)
target.cost_center = item.get("selling_cost_center") \ cost_center = item.get("selling_cost_center") \
or item_group.get("selling_cost_center") or item_group.get("selling_cost_center")
if cost_center:
target.cost_center = cost_center
doclist = get_mapped_doc("Sales Order", source_name, { doclist = get_mapped_doc("Sales Order", source_name, {
"Sales Order": { "Sales Order": {
"doctype": "Sales Invoice", "doctype": "Sales Invoice",

View File

@ -204,7 +204,7 @@ class Company(NestedSet):
}) })
for default_account in default_accounts: 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)) self._set_default_account(default_account, default_accounts.get(default_account))
if not self.default_income_account: if not self.default_income_account:

View File

@ -66,7 +66,7 @@ def place_order():
from erpnext.selling.doctype.quotation.quotation import _make_sales_order from erpnext.selling.doctype.quotation.quotation import _make_sales_order
sales_order = frappe.get_doc(_make_sales_order(quotation.name, ignore_permissions=True)) sales_order = frappe.get_doc(_make_sales_order(quotation.name, ignore_permissions=True))
if not cart_settings.allow_items_not_in_stock: if not cint(cart_settings.allow_items_not_in_stock):
for item in sales_order.get("items"): for item in sales_order.get("items"):
item.reserved_warehouse, is_stock_item = frappe.db.get_value("Item", item.reserved_warehouse, is_stock_item = frappe.db.get_value("Item",
item.item_code, ["website_warehouse", "is_stock_item"]) item.item_code, ["website_warehouse", "is_stock_item"])

View File

@ -241,7 +241,9 @@ class StockEntry(StockController):
for d in self.get("items"): for d in self.get("items"):
if not d.expense_account: if not d.expense_account:
frappe.throw(_("Please enter Difference Account")) frappe.throw(_("Please enter <b>Difference Account</b> or set default <b>Stock Adjustment Account</b> for company {0}")
.format(frappe.bold(self.company)))
elif self.is_opening == "Yes" and frappe.db.get_value("Account", d.expense_account, "report_type") == "Profit and Loss": elif self.is_opening == "Yes" and frappe.db.get_value("Account", d.expense_account, "report_type") == "Profit and Loss":
frappe.throw(_("Difference Account must be a Asset/Liability type account, since this Stock Entry is an Opening Entry"), OpeningEntryAccountError) frappe.throw(_("Difference Account must be a Asset/Liability type account, since this Stock Entry is an Opening Entry"), OpeningEntryAccountError)

View File

@ -22,7 +22,6 @@ class Issue(Document):
return "{0}: {1}".format(_(self.status), self.subject) return "{0}: {1}".format(_(self.status), self.subject)
def validate(self): def validate(self):
self.flags.ignore_disabled = 1
if self.is_new() and self.via_customer_portal: if self.is_new() and self.via_customer_portal:
self.flags.create_communication = True self.flags.create_communication = True

View File

@ -2,7 +2,7 @@
<div class="row no-gutters"> <div class="row no-gutters">
<div class="col-md-3"> <div class="col-md-3">
<div class="card-body"> <div class="card-body">
<a class="no-underline" href="{{ item.route }}"> <a class="no-underline" href="/{{ item.route }}">
<img class="website-image" src="{{ item.website_image or item.image or 'no-image.jpg' }}" alt="{{ item.item_name }}"> <img class="website-image" src="{{ item.website_image or item.image or 'no-image.jpg' }}" alt="{{ item.item_name }}">
</a> </a>
</div> </div>
@ -10,14 +10,14 @@
<div class="col-md-9"> <div class="col-md-9">
<div class="card-body"> <div class="card-body">
<h5 class="card-title"> <h5 class="card-title">
<a class="text-dark" href="{{ item.route }}"> <a class="text-dark" href="/{{ item.route }}">
{{ item.item_name or item.name }} {{ item.item_name or item.name }}
</a> </a>
</h5> </h5>
<p class="card-text"> <p class="card-text">
{{ item.website_description or item.description or '<i class="text-muted">No description</i>' }} {{ item.website_description or item.description or '<i class="text-muted">No description</i>' }}
</p> </p>
<a href="{{ item.route }}" class="btn btn-sm btn-light">{{ _('More details') }}</a> <a href="/{{ item.route }}" class="btn btn-sm btn-light">{{ _('More details') }}</a>
</div> </div>
</div> </div>
</div> </div>