Merge branch 'hotfix'

This commit is contained in:
Frappe Bot 2019-02-15 10:22:32 +00:00
commit 58dda68430
19 changed files with 99 additions and 77 deletions

View File

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

View File

@ -60,7 +60,7 @@ def get_booking_dates(doc, item, start_date=None, end_date=None):
deferred_account = "deferred_revenue_account" if doc.doctype=="Sales Invoice" else "deferred_expense_account"
last_gl_entry, skip = False, False
booking_end_date = getdate(add_days(today(), -1)) if not end_date else end_date
booking_end_date = getdate(add_days(today(), -1) if not end_date else end_date)
if booking_end_date < item.service_start_date or \
(item.service_stop_date and booking_end_date.month > item.service_stop_date.month):
return None, None, None, True
@ -71,7 +71,7 @@ def get_booking_dates(doc, item, start_date=None, end_date=None):
last_gl_entry = True
booking_end_date = item.service_stop_date
booking_start_date = getdate(add_months(today(), -1)) if not start_date else start_date
booking_start_date = getdate(add_months(today(), -1) if not start_date else start_date)
booking_start_date = booking_start_date \
if booking_start_date > item.service_start_date else item.service_start_date
@ -113,7 +113,6 @@ def calculate_amount_and_base_amount(doc, item, last_gl_entry, total_days, total
group by voucher_detail_no
'''.format(total_credit_debit, total_credit_debit_currency),
(doc.company, item.get(deferred_account), doc.doctype, doc.name, item.name), as_dict=True)
already_booked_amount = gl_entries_details[0].total_credit if gl_entries_details else 0
base_amount = flt(item.base_net_amount - already_booked_amount, item.precision("base_net_amount"))
if account_currency==doc.company_currency:
@ -140,7 +139,7 @@ def book_deferred_income_or_expense(doc, start_date=None, end_date=None):
get_booking_dates(doc, item, start_date, end_date)
if skip: continue
total_days = date_diff(item.service_end_date, item.service_start_date)
total_days = date_diff(item.service_end_date, item.service_start_date) + 1
total_booking_days = date_diff(booking_end_date, booking_start_date) + 1
account_currency = get_account_currency(item.expense_account)
@ -179,6 +178,10 @@ def book_deferred_income_or_expense(doc, start_date=None, end_date=None):
'project': project
}, account_currency)
)
if gl_entries:
make_gl_entries(gl_entries, cancel=(doc.docstatus == 2), merge_entries=True)
try:
make_gl_entries(gl_entries, cancel=(doc.docstatus == 2), merge_entries=True)
frappe.db.commit()
except:
frappe.db.rollback()
frappe.log_error(message = frappe.get_traceback(), title = _("Error while processing deferred accounting for {0}").format(doc.name))

View File

@ -101,7 +101,7 @@ def set_account_currency(filters):
frappe.db.get_value(filters.party_type, filters.party[0], "default_currency"))
filters["account_currency"] = account_currency or filters.company_currency
if filters.account_currency != filters.company_currency:
if filters.account_currency != filters.company_currency and not filters.presentation_currency:
filters.presentation_currency = filters.account_currency
return filters

View File

@ -104,7 +104,7 @@ def convert_to_presentation_currency(gl_entries, currency_info):
credit_in_account_currency = flt(entry['credit_in_account_currency'])
account_currency = entry['account_currency']
if account_currency != presentation_currency or (account_currency == presentation_currency and not is_p_or_l_account(account)):
if account_currency != presentation_currency:
value = debit or credit
date = currency_info['report_date'] if not is_p_or_l_account(account) else entry['posting_date']

View File

@ -615,7 +615,7 @@ def get_held_invoices(party_type, party):
return held_invoices
def get_outstanding_invoices(party_type, party, account, condition=None, limit=1000):
def get_outstanding_invoices(party_type, party, account, condition=None, limit=None):
outstanding_invoices = []
precision = frappe.get_precision("Sales Invoice", "outstanding_amount") or 2
@ -628,7 +628,7 @@ def get_outstanding_invoices(party_type, party, account, condition=None, limit=1
invoice = 'Sales Invoice' if erpnext.get_party_account_type(party_type) == 'Receivable' else 'Purchase Invoice'
held_invoices = get_held_invoices(party_type, party)
limit_cond = "limit %s" % (limit or 1000)
limit_cond = "limit %s" % limit if limit else ""
invoice_list = frappe.db.sql("""
select

View File

@ -456,7 +456,7 @@ def make_rm_stock_entry(purchase_order, rm_items):
items_dict = {
rm_item_code: {
"item_name": rm_item_data["item_name"],
"description": item_wh[rm_item_code].get('description'),
"description": item_wh.get(rm_item_code, {}).get('description', ""),
'qty': rm_item_data["qty"],
'from_warehouse': rm_item_data["warehouse"],
'stock_uom': rm_item_data["stock_uom"],

View File

@ -1,12 +1,13 @@
{
"add_total_row": 0,
"add_total_row": 1,
"creation": "2018-10-05 16:08:24.156448",
"disable_prepared_report": 0,
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
"modified": "2018-10-05 16:08:33.272201",
"modified": "2019-02-12 14:32:29.107109",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Analytics",

View File

@ -276,8 +276,8 @@ class ProductionPlan(Document):
item_dict[(d.item_code, d.material_request_item, d.warehouse)] = item_details
else:
item_details.update({
"qty":flt(item_dict.get((d.item_code, d.sales_order, d.warehouse),{})
.get("qty")) + flt(d.planned_qty)
"qty": flt(item_dict.get((d.item_code, d.sales_order, d.warehouse),{})
.get("qty")) + (flt(d.planned_qty) - flt(d.ordered_qty))
})
item_dict[(d.item_code, d.sales_order, d.warehouse)] = item_details

View File

@ -1,13 +1,14 @@
{
"add_total_row": 0,
"add_total_row": 1,
"creation": "2018-10-11 19:28:37.085066",
"disable_prepared_report": 0,
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
"letter_head": "",
"modified": "2018-10-11 19:28:37.085066",
"modified": "2019-02-12 14:32:16.392521",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Production Analytics",

View File

@ -19,9 +19,10 @@ def execute():
SELECT
parent, SUM(qty) as qty
FROM
`tab%s Item`
`tab{0} Item`
where parenttype = '{0}'
GROUP BY parent
''' % (doctype), as_dict = True)
'''.format(doctype), as_dict = True)
# Query to update total_qty might become too big, Update in batches
# batch_size is chosen arbitrarily, Don't try too hard to reason about it

View File

@ -18,7 +18,7 @@ frappe.ui.form.on("Timesheet", {
return{
filters: {
'project': child.project,
'status': ["!=", "Closed"]
'status': ["!=", "Cancelled"]
}
}
}

View File

@ -276,13 +276,11 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
scan_barcode: function() {
let scan_barcode_field = this.frm.fields_dict["scan_barcode"];
let show_description = function(idx, item_code, exist=null) {
if(exist) {
scan_barcode_field.set_new_description(__('Row : ') + idx + ' ' +
item_code + __(' Qty increased by 1'));
let show_description = function(idx, exist = null) {
if (exist) {
scan_barcode_field.set_new_description(__('Row #{0}: Qty increased by 1', [idx]));
} else {
scan_barcode_field.set_new_description(__('New row : ') + idx + ' ' +
item_code + __(' Created'));
scan_barcode_field.set_new_description(__('Row #{0}: Item added', [idx]));
}
}
@ -291,39 +289,39 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
method: "erpnext.selling.page.point_of_sale.point_of_sale.search_serial_or_batch_or_barcode_number",
args: { search_value: this.frm.doc.scan_barcode }
}).then(r => {
if(r && r.message && r.message.item_code) {
let child = "";
let add_row_index = -1;
let cur_grid= this.frm.fields_dict["items"].grid;
this.frm.doc.items.map(d => {
if(d.item_code==r.message.item_code){
add_row_index = d.idx;
return;
} else if(!d.item_code && add_row_index==-1) {
add_row_index = d.idx;
}
});
if(add_row_index == -1) {
child = frappe.model.add_child(this.frm.doc, cur_grid.doctype, "items", add_row_index);
} else {
child = cur_grid.get_grid_row(add_row_index-1).doc;
}
show_description(child.idx, r.message.item_code, child.item_code);
frappe.model.set_value(child.doctype, child.name, {
item_code: r.message.item_code,
qty: (child.qty || 0) + 1,
barcode: r.message.barcode
});
const data = r && r.message;
if (!data) {
scan_barcode_field.set_new_description(__('Cannot find Item with this barcode'));
return;
}
else{
scan_barcode_field.set_new_description(this.frm.doc.scan_barcode +__(' does not exist!'));
let cur_grid = this.frm.fields_dict.items.grid;
let row_to_modify = null;
const existing_item_row = this.frm.doc.items.find(d => d.item_code === data.item_code);
const blank_item_row = this.frm.doc.items.find(d => !d.item_code);
if (existing_item_row) {
row_to_modify = existing_item_row;
} else if (blank_item_row) {
row_to_modify = blank_item_row;
}
if (!row_to_modify) {
// add new row
row_to_modify = frappe.model.add_child(this.frm.doc, cur_grid.doctype, 'items');
}
show_description(row_to_modify.idx, row_to_modify.item_code);
frappe.model.set_value(row_to_modify.doctype, row_to_modify.name, {
item_code: data.item_code,
qty: (row_to_modify.qty || 0) + 1
});
this.frm.refresh_field('items');
});
scan_barcode_field.set_value("");
scan_barcode_field.set_value('');
}
return false;
},

View File

@ -345,13 +345,14 @@ def set_tax_withholding_category(company):
if company and tds_account:
accounts = [dict(company=company, account=tds_account)]
fiscal_year = get_fiscal_year(today(), company=accounts[0].get('company'))[0]
fiscal_year = get_fiscal_year(today(), company=company)[0]
docs = get_tds_details(accounts, fiscal_year)
for d in docs:
try:
doc = frappe.get_doc(d)
doc.flags.ignore_permissions = True
doc.flags.ignore_mandatory = True
doc.insert()
except frappe.DuplicateEntryError:
doc = frappe.get_doc("Tax Withholding Category", d.get("name"))

View File

@ -102,7 +102,8 @@ def get_party_details(party_type, party_list, doctype, party_details):
records = frappe.get_list(doctype, filters=filters, fields=fields, as_list=True)
for d in records:
details = party_details.get(d[0])
details.setdefault(frappe.scrub(doctype), []).append(d[1:])
if details:
details.setdefault(frappe.scrub(doctype), []).append(d[1:])
return party_details

View File

@ -1,12 +1,13 @@
{
"add_total_row": 0,
"add_total_row": 1,
"creation": "2018-09-21 12:46:29.451048",
"disable_prepared_report": 0,
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
"modified": "2018-09-21 12:46:29.451048",
"modified": "2019-02-12 14:30:40.043652",
"modified_by": "Administrator",
"module": "Selling",
"name": "Sales Analytics",

View File

@ -700,15 +700,14 @@ class Item(WebsiteGenerator):
frappe.db.get_single_value('Item Variant Settings', 'do_not_update_variants'):
return
if self.has_variants:
updated = []
variants = frappe.db.get_all("Item", fields=["item_code"], filters={"variant_of": self.name})
for d in variants:
variant = frappe.get_doc("Item", d)
copy_attributes_to_variant(self, variant)
variant.save()
updated.append(d.item_code)
if updated:
frappe.msgprint(_("Item Variants {0} updated").format(", ".join(updated)))
if variants:
if len(variants) <= 30:
update_variants(variants, self, publish_progress=False)
frappe.msgprint(_("Item Variants updated"))
else:
frappe.enqueue("erpnext.stock.doctype.item.item.update_variants",
variants=variants, template=self, now=frappe.flags.in_test, timeout=600)
def validate_has_variants(self):
if not self.has_variants and frappe.db.get_value("Item", self.name, "has_variants"):
@ -997,3 +996,13 @@ def get_item_attribute(parent, attribute_value=''):
return frappe.get_all("Item Attribute Value", fields = ["attribute_value"],
filters = {'parent': parent, 'attribute_value': ("like", "%%%s%%" % attribute_value)})
def update_variants(variants, template, publish_progress=True):
count=0
for d in variants:
variant = frappe.get_doc("Item", d)
copy_attributes_to_variant(template, variant)
variant.save()
count+=1
if publish_progress:
frappe.publish_progress(count*100/len(variants), title = _("Updating Variants..."))

View File

@ -293,8 +293,9 @@ class StockEntry(StockController):
total_completed_qty = flt(self.fg_completed_qty) + flt(prod_order.produced_qty)
completed_qty = d.completed_qty + (allowance_percentage/100 * d.completed_qty)
if total_completed_qty > flt(completed_qty):
frappe.throw(_("Row #{0}: Operation {1} is not completed for {2} qty of finished goods in Work Order # {3}. Please update operation status via Time Logs")
.format(d.idx, d.operation, total_completed_qty, self.work_order), OperationsNotCompleteError)
job_card = frappe.db.get_value('Job Card', {'operation_id': d.name}, 'name')
frappe.throw(_("Row #{0}: Operation {1} is not completed for {2} qty of finished goods in Work Order # {3}. Please update operation status via Job Card # {4}")
.format(d.idx, d.operation, total_completed_qty, self.work_order, job_card), OperationsNotCompleteError)
def check_duplicate_entry_for_work_order(self):
other_ste = [t[0] for t in frappe.db.get_values("Stock Entry", {

View File

@ -16,6 +16,9 @@ from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
from six import string_types, iteritems
sales_doctypes = ['Quotation', 'Sales Order', 'Delivery Note', 'Sales Invoice']
purchase_doctypes = ['Material Request', 'Supplier Quotation', 'Purchase Order', 'Purchase Receipt', 'Purchase Invoice']
@frappe.whitelist()
def get_item_details(args):
"""
@ -228,7 +231,7 @@ def get_basic_details(args, item):
#Set the UOM to the Default Sales UOM or Default Purchase UOM if configured in the Item Master
if not args.uom:
if args.get('doctype') in ['Quotation', 'Sales Order', 'Delivery Note', 'Sales Invoice']:
if args.get('doctype') in sales_doctypes:
args.uom = item.sales_uom if item.sales_uom else item.stock_uom
elif (args.get('doctype') in ['Purchase Order', 'Purchase Receipt', 'Purchase Invoice']) or \
(args.get('doctype') == 'Material Request' and args.get('material_request_type') == 'Purchase'):
@ -281,14 +284,15 @@ def get_basic_details(args, item):
out.conversion_factor = 1.0
else:
out.conversion_factor = args.conversion_factor or \
get_conversion_factor(item.item_code, args.uom).get("conversion_factor")
get_conversion_factor(item.name, args.uom).get("conversion_factor")
args.conversion_factor = out.conversion_factor
out.stock_qty = out.qty * out.conversion_factor
# calculate last purchase rate
from erpnext.buying.doctype.purchase_order.purchase_order import item_last_purchase_rate
out.last_purchase_rate = item_last_purchase_rate(args.name, args.conversion_rate, item.item_code, out.conversion_factor)
if args.get('doctype') in purchase_doctypes:
from erpnext.buying.doctype.purchase_order.purchase_order import item_last_purchase_rate
out.last_purchase_rate = item_last_purchase_rate(args.name, args.conversion_rate, item.name, out.conversion_factor)
# if default specified in item is for another company, fetch from company
for d in [

View File

@ -1,12 +1,13 @@
{
"add_total_row": 0,
"add_total_row": 1,
"creation": "2018-10-08 12:11:32.133020",
"disable_prepared_report": 0,
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
"modified": "2018-10-08 12:18:42.834270",
"modified": "2019-02-12 14:32:22.874082",
"modified_by": "Administrator",
"module": "Stock",
"name": "Stock Analytics",