Compare commits

..

4 Commits

Author SHA1 Message Date
Sahil Khan
b4ce43306b Merge branch 'v11-pre-release' into version-11 2019-12-18 13:59:59 +05:30
Sahil Khan
85a9f55fa7 bumped to version 11.1.71 2019-12-18 14:19:59 +05:50
Suraj Shetty
596c0d2060 fix(init): bump version to 11.1.70 (#19986)
fix(init): bump version to 11.1.70
2019-12-18 13:58:01 +05:30
sahil28297
723421f375 fix(init): bump version to 11.1.70 2019-12-18 13:56:34 +05:30
47 changed files with 194 additions and 329 deletions

View File

@@ -1,14 +0,0 @@
name: Trigger Docker build on release
on:
release:
types: [released]
jobs:
curl:
runs-on: ubuntu-latest
container:
image: alpine:latest
steps:
- name: curl
run: |
apk add curl bash
curl -s -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Travis-API-Version: 3" -H "Authorization: token ${{ secrets.TRAVIS_CI_TOKEN }}" -d '{"request":{"branch":"master"}}' https://api.travis-ci.com/repo/frappe%2Ffrappe_docker/requests

View File

@@ -76,6 +76,5 @@ install:
- bench --site test_site reinstall --yes
after_script:
- pip install coverage==4.5.4
- pip install python-coveralls
- coveralls -b apps/erpnext -d ../../sites/.coverage

View File

@@ -5,7 +5,7 @@ import frappe
from erpnext.hooks import regional_overrides
from frappe.utils import getdate
__version__ = '11.1.68'
__version__ = '11.1.71'
def get_default_company(user=None):
'''Get default company for user'''
@@ -144,4 +144,4 @@ def is_member():
last_membership = get_last_membership()
if last_membership and getdate(last_membership.to_date) > getdate():
return True
return False
return False

View File

@@ -6,7 +6,6 @@ from __future__ import unicode_literals
import frappe, json
from frappe.model.document import Document
from frappe import _
from frappe.desk.search import sanitize_searchfield
class BankGuarantee(Document):
def validate(self):
@@ -23,8 +22,5 @@ class BankGuarantee(Document):
@frappe.whitelist()
def get_vouchar_detials(column_list, doctype, docname):
column_list = json.loads(column_list)
for col in column_list:
sanitize_searchfield(col)
return frappe.db.sql(''' select {columns} from `tab{doctype}` where name=%s'''
.format(columns=", ".join(json.loads(column_list)), doctype=doctype), docname, as_dict=1)[0]

View File

@@ -2454,7 +2454,7 @@
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "other_charges_calculation",
"fieldtype": "Long Text",
"fieldtype": "Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -4903,7 +4903,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2020-04-16 19:04:18.599264",
"modified": "2019-04-22 12:45:49.728359",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice",

View File

@@ -16,7 +16,7 @@ frappe.listview_settings['Purchase Invoice'] = {
} else if(frappe.datetime.get_diff(doc.due_date) < 0) {
return [__("Overdue"), "red", "outstanding_amount,>,0|due_date,<,Today"];
} else {
return [__("Unpaid"), "orange", "outstanding_amount,>,0|due_date,>=,Today"];
return [__("Unpaid"), "orange", "outstanding_amount,>,0|due,>=,Today"];
}
} else if(cint(doc.is_return)) {
return [__("Return"), "darkgrey", "is_return,=,Yes"];

View File

@@ -2544,7 +2544,7 @@
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "other_charges_calculation",
"fieldtype": "Long Text",
"fieldtype": "Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -5816,7 +5816,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2020-04-16 19:05:00.498772",
"modified": "2019-04-22 12:45:41.109345",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",

View File

@@ -4,141 +4,126 @@
from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.utils import formatdate, flt, add_days
from frappe.utils import formatdate, getdate, flt, add_days
def execute(filters=None):
filters.day_before_from_date = add_days(filters.from_date, -1)
columns, data = get_columns(filters), get_data(filters)
return columns, data
def get_data(filters):
data = []
asset_categories = get_asset_categories(filters)
assets = get_assets(filters)
asset_costs = get_asset_costs(assets, filters)
asset_depreciations = get_accumulated_depreciations(assets, filters)
for asset_category in asset_categories:
row = frappe._dict()
# row.asset_category = asset_category
row.update(asset_category)
row.cost_as_on_to_date = (flt(row.cost_as_on_from_date) + flt(row.cost_of_new_purchase) -
flt(row.cost_of_sold_asset) - flt(row.cost_of_scrapped_asset))
row.update(next(asset for asset in assets if asset["asset_category"] == asset_category.get("asset_category", "")))
row.accumulated_depreciation_as_on_to_date = (flt(row.accumulated_depreciation_as_on_from_date) +
flt(row.depreciation_amount_during_the_period) - flt(row.depreciation_eliminated))
row.net_asset_value_as_on_from_date = (flt(row.cost_as_on_from_date) -
flt(row.accumulated_depreciation_as_on_from_date))
row.net_asset_value_as_on_to_date = (flt(row.cost_as_on_to_date) -
flt(row.accumulated_depreciation_as_on_to_date))
row.asset_category = asset_category
row.update(asset_costs.get(asset_category))
row.cost_as_on_to_date = (flt(row.cost_as_on_from_date) + flt(row.cost_of_new_purchase)
- flt(row.cost_of_sold_asset) - flt(row.cost_of_scrapped_asset))
row.update(asset_depreciations.get(asset_category))
row.accumulated_depreciation_as_on_to_date = (flt(row.accumulated_depreciation_as_on_from_date) +
flt(row.depreciation_amount_during_the_period) - flt(row.depreciation_eliminated))
row.net_asset_value_as_on_from_date = (flt(row.cost_as_on_from_date) -
flt(row.accumulated_depreciation_as_on_from_date))
row.net_asset_value_as_on_to_date = (flt(row.cost_as_on_to_date) -
flt(row.accumulated_depreciation_as_on_to_date))
data.append(row)
return data
def get_asset_categories(filters):
return frappe.db.sql("""
SELECT asset_category,
ifnull(sum(case when purchase_date < %(from_date)s then
case when ifnull(disposal_date, 0) = 0 or disposal_date >= %(from_date)s then
gross_purchase_amount
else
0
end
else
0
end), 0) as cost_as_on_from_date,
ifnull(sum(case when purchase_date >= %(from_date)s then
gross_purchase_amount
else
0
end), 0) as cost_of_new_purchase,
ifnull(sum(case when ifnull(disposal_date, 0) != 0
and disposal_date >= %(from_date)s
and disposal_date <= %(to_date)s then
case when status = "Sold" then
gross_purchase_amount
else
0
end
else
0
end), 0) as cost_of_sold_asset,
ifnull(sum(case when ifnull(disposal_date, 0) != 0
and disposal_date >= %(from_date)s
and disposal_date <= %(to_date)s then
case when status = "Scrapped" then
gross_purchase_amount
else
0
end
else
0
end), 0) as cost_of_scrapped_asset
from `tabAsset`
where docstatus=1 and company=%(company)s and purchase_date <= %(to_date)s
group by asset_category
""", {"to_date": filters.to_date, "from_date": filters.from_date, "company": filters.company}, as_dict=1)
return frappe.db.sql_list("""
select distinct asset_category from `tabAsset`
where docstatus=1 and company=%s and purchase_date <= %s
""", (filters.company, filters.to_date))
def get_assets(filters):
return frappe.db.sql("""
SELECT results.asset_category,
sum(results.accumulated_depreciation_as_on_from_date) as accumulated_depreciation_as_on_from_date,
sum(results.depreciation_eliminated_during_the_period) as depreciation_eliminated_during_the_period,
sum(results.depreciation_amount_during_the_period) as depreciation_amount_during_the_period
from (SELECT a.asset_category,
ifnull(sum(a.opening_accumulated_depreciation +
case when ds.schedule_date < %(from_date)s and
(ifnull(a.disposal_date, 0) = 0 or a.disposal_date >= %(from_date)s) then
ds.depreciation_amount
else
0
end), 0) as accumulated_depreciation_as_on_from_date,
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 and a.disposal_date >= %(from_date)s
and a.disposal_date <= %(to_date)s and ds.schedule_date <= a.disposal_date then
ds.depreciation_amount
else
0
end), 0) as depreciation_eliminated_during_the_period,
select name, asset_category, purchase_date, gross_purchase_amount, disposal_date, status
from `tabAsset`
where docstatus=1 and company=%s and purchase_date <= %s""",
(filters.company, filters.to_date), as_dict=1)
def get_asset_costs(assets, filters):
asset_costs = frappe._dict()
for d in assets:
asset_costs.setdefault(d.asset_category, frappe._dict({
"cost_as_on_from_date": 0,
"cost_of_new_purchase": 0,
"cost_of_sold_asset": 0,
"cost_of_scrapped_asset": 0
}))
costs = asset_costs[d.asset_category]
if getdate(d.purchase_date) < getdate(filters.from_date):
if not d.disposal_date or getdate(d.disposal_date) >= getdate(filters.from_date):
costs.cost_as_on_from_date += flt(d.gross_purchase_amount)
else:
costs.cost_of_new_purchase += flt(d.gross_purchase_amount)
if d.disposal_date and getdate(d.disposal_date) >= getdate(filters.from_date) \
and getdate(d.disposal_date) <= getdate(filters.to_date):
if d.status == "Sold":
costs.cost_of_sold_asset += flt(d.gross_purchase_amount)
elif d.status == "Scrapped":
costs.cost_of_scrapped_asset += flt(d.gross_purchase_amount)
return asset_costs
def get_accumulated_depreciations(assets, filters):
asset_depreciations = frappe._dict()
for d in assets:
asset = frappe.get_doc("Asset", d.name)
if d.asset_category in asset_depreciations:
asset_depreciations[d.asset_category]['accumulated_depreciation_as_on_from_date'] += asset.opening_accumulated_depreciation
else:
asset_depreciations.setdefault(d.asset_category, frappe._dict({
"accumulated_depreciation_as_on_from_date": asset.opening_accumulated_depreciation,
"depreciation_amount_during_the_period": 0,
"depreciation_eliminated_during_the_period": 0
}))
ifnull(sum(case when ds.schedule_date >= %(from_date)s and ds.schedule_date <= %(to_date)s
and (ifnull(a.disposal_date, 0) = 0 or ds.schedule_date <= a.disposal_date) then
ds.depreciation_amount
else
0
end), 0) as depreciation_amount_during_the_period
from `tabAsset` a, `tabDepreciation Schedule` ds
where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s and a.name = ds.parent
group by a.asset_category
union
SELECT a.asset_category,
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0
and (a.disposal_date < %(from_date)s or a.disposal_date > %(to_date)s) then
0
else
a.opening_accumulated_depreciation
end), 0) as accumulated_depreciation_as_on_from_date,
ifnull(sum(case when a.disposal_date >= %(from_date)s and a.disposal_date <= %(to_date)s then
a.opening_accumulated_depreciation
else
0
end), 0) as depreciation_eliminated_during_the_period,
0 as depreciation_amount_during_the_period
from `tabAsset` a
where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s
and not exists(select * from `tabDepreciation Schedule` ds where a.name = ds.parent)
group by a.asset_category) as results
group by results.asset_category
""", {"to_date": filters.to_date, "from_date": filters.from_date, "company": filters.company}, as_dict=1)
depr = asset_depreciations[d.asset_category]
if not asset.schedules: # if no schedule,
if asset.disposal_date:
# and disposal is NOT within the period, then opening accumulated depreciation not included
if getdate(asset.disposal_date) < getdate(filters.from_date) or getdate(asset.disposal_date) > getdate(filters.to_date):
asset_depreciations[d.asset_category]['accumulated_depreciation_as_on_from_date'] = 0
# if no schedule, and disposal is within period, accumulated dep is the amount eliminated
if getdate(asset.disposal_date) >= getdate(filters.from_date) and getdate(asset.disposal_date) <= getdate(filters.to_date):
depr.depreciation_eliminated_during_the_period += asset.opening_accumulated_depreciation
for schedule in asset.get("schedules"):
if getdate(schedule.schedule_date) < getdate(filters.from_date):
if not asset.disposal_date or getdate(asset.disposal_date) >= getdate(filters.from_date):
depr.accumulated_depreciation_as_on_from_date += flt(schedule.depreciation_amount)
elif getdate(schedule.schedule_date) <= getdate(filters.to_date):
if not asset.disposal_date:
depr.depreciation_amount_during_the_period += flt(schedule.depreciation_amount)
else:
if getdate(schedule.schedule_date) <= getdate(asset.disposal_date):
depr.depreciation_amount_during_the_period += flt(schedule.depreciation_amount)
if asset.disposal_date and getdate(asset.disposal_date) >= getdate(filters.from_date) and getdate(asset.disposal_date) <= getdate(filters.to_date):
if getdate(schedule.schedule_date) <= getdate(asset.disposal_date):
depr.depreciation_eliminated_during_the_period += flt(schedule.depreciation_amount)
return asset_depreciations
def get_columns(filters):
return [
{

View File

@@ -286,14 +286,14 @@ class PartyLedgerSummaryReport(object):
if parties and accounts:
if len(parties) == 1:
party = list(parties.keys())[0]
party = parties.keys()[0]
for account, amount in iteritems(accounts):
self.party_adjustment_accounts.add(account)
self.party_adjustment_details.setdefault(party, {})
self.party_adjustment_details[party].setdefault(account, 0)
self.party_adjustment_details[party][account] += amount
elif len(accounts) == 1 and not has_irrelevant_entry:
account = list(accounts.keys())[0]
account = accounts.keys()[0]
self.party_adjustment_accounts.add(account)
for party, amount in iteritems(parties):
self.party_adjustment_details.setdefault(party, {})

View File

@@ -2176,7 +2176,7 @@
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "other_charges_calculation",
"fieldtype": "Long Text",
"fieldtype": "Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -3948,7 +3948,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2020-04-16 18:54:54.840653",
"modified": "2019-06-24 20:55:03.466766",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order",

View File

@@ -1395,7 +1395,7 @@
"collapsible": 0,
"columns": 0,
"fieldname": "other_charges_calculation",
"fieldtype": "Long Text",
"fieldtype": "Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -2845,7 +2845,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2020-04-16 19:05:41.924303",
"modified": "2019-01-07 16:52:01.505553",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier Quotation",

View File

@@ -138,7 +138,7 @@ def refresh_scorecards():
# Check to see if any new scorecard periods are created
if make_all_scorecards(sc.name) > 0:
# Save the scorecard to update the score and standings
frappe.get_doc('Supplier Scorecard', sc.name).save()
sc.save()
@frappe.whitelist()

View File

@@ -311,7 +311,6 @@ def get_batch_no(doctype, txt, searchfield, start, page_len, filters):
and sle.item_code = %(item_code)s
and sle.warehouse = %(warehouse)s
and (sle.batch_no like %(txt)s
or batch.expiry_date like %(txt)s
or batch.manufacturing_date like %(txt)s)
and batch.docstatus < 2
{cond}
@@ -330,7 +329,6 @@ def get_batch_no(doctype, txt, searchfield, start, page_len, filters):
where batch.disabled = 0
and item = %(item_code)s
and (name like %(txt)s
or expiry_date like %(txt)s
or manufacturing_date like %(txt)s)
and docstatus < 2
{0}

View File

@@ -54,7 +54,6 @@ class StockController(AccountsController):
gl_list = []
warehouse_with_no_account = []
precision = frappe.get_precision('GL Entry', 'debit_in_account_currency')
for item_row in voucher_details:
sle_list = sle_map.get(item_row.name)
if sle_list:
@@ -80,7 +79,7 @@ class StockController(AccountsController):
"against": item_row.expense_account,
"cost_center": item_row.cost_center,
"remarks": self.get("remarks") or "Accounting Entry for Stock",
"debit": flt(sle.stock_value_difference, precision),
"debit": flt(sle.stock_value_difference, 2),
"is_opening": item_row.get("is_opening") or self.get("is_opening") or "No",
}, warehouse_account[sle.warehouse]["account_currency"]))
@@ -90,7 +89,7 @@ class StockController(AccountsController):
"against": warehouse_account[sle.warehouse]["account"],
"cost_center": item_row.cost_center,
"remarks": self.get("remarks") or "Accounting Entry for Stock",
"credit": flt(sle.stock_value_difference, precision),
"credit": flt(sle.stock_value_difference, 2),
"project": item_row.get("project") or self.get("project"),
"is_opening": item_row.get("is_opening") or self.get("is_opening") or "No"
}))

View File

@@ -305,19 +305,11 @@ class calculate_taxes_and_totals(object):
last_tax = self.doc.get("taxes")[-1]
non_inclusive_tax_amount = sum([flt(d.tax_amount_after_discount_amount)
for d in self.doc.get("taxes") if not d.included_in_print_rate])
diff = self.doc.total + non_inclusive_tax_amount \
- flt(last_tax.total, last_tax.precision("total"))
# If discount amount applied, deduct the discount amount
# because self.doc.total is always without discount, but last_tax.total is after discount
if self.discount_amount_applied and self.doc.discount_amount:
diff -= flt(self.doc.discount_amount)
diff = flt(diff, self.doc.precision("rounding_adjustment"))
if diff and abs(diff) <= (5.0 / 10**last_tax.precision("tax_amount")):
self.doc.rounding_adjustment = diff
self.doc.rounding_adjustment = flt(flt(self.doc.rounding_adjustment) +
flt(diff), self.doc.precision("rounding_adjustment"))
def calculate_totals(self):
self.doc.grand_total = flt(self.doc.get("taxes")[-1].total) + flt(self.doc.rounding_adjustment) \

View File

@@ -234,17 +234,14 @@ def get_order_taxes(shopify_order, shopify_settings):
return taxes
def update_taxes_with_shipping_lines(taxes, shipping_lines, shopify_settings):
"""Shipping lines represents the shipping details,
each such shipping detail consists of a list of tax_lines"""
for shipping_charge in shipping_lines:
for tax in shipping_charge.get("tax_lines"):
taxes.append({
"charge_type": _("Actual"),
"account_head": get_tax_account_head(tax),
"description": tax["title"],
"tax_amount": tax["price"],
"cost_center": shopify_settings.cost_center
})
taxes.append({
"charge_type": _("Actual"),
"account_head": get_tax_account_head(shipping_charge),
"description": shipping_charge["title"],
"tax_amount": shipping_charge["price"],
"cost_center": shopify_settings.cost_center
})
return taxes

View File

@@ -114,11 +114,10 @@ def add_account_subtype(account_subtype):
@frappe.whitelist()
def sync_transactions(bank, bank_account):
'''Sync transactions based on the last integration date as the start date, after sync is completed
add the transaction date of the oldest transaction as the last integration date'''
last_transaction_date = frappe.db.get_value("Bank Account", bank_account, "last_integration_date")
if last_transaction_date:
start_date = formatdate(last_transaction_date, "YYYY-MM-dd")
last_sync_date = frappe.db.get_value("Bank Account", bank_account, "last_integration_date")
if last_sync_date:
start_date = formatdate(last_sync_date, "YYYY-MM-dd")
else:
start_date = formatdate(add_months(today(), -12), "YYYY-MM-dd")
end_date = formatdate(today(), "YYYY-MM-dd")
@@ -126,17 +125,13 @@ def sync_transactions(bank, bank_account):
try:
transactions = get_transactions(bank=bank, bank_account=bank_account, start_date=start_date, end_date=end_date)
result = []
for transaction in reversed(transactions):
result += new_bank_transaction(transaction)
if transactions:
for transaction in transactions:
result.append(new_bank_transaction(transaction))
if result:
last_transaction_date = frappe.db.get_value('Bank Transaction', result.pop(), 'date')
frappe.logger().info("Plaid added {} new Bank Transactions from '{}' between {} and {}".format(
len(result), bank_account, start_date, end_date))
frappe.db.set_value("Bank Account", bank_account, "last_integration_date", last_transaction_date)
frappe.db.set_value("Bank Account", bank_account, "last_integration_date", getdate(end_date))
return result
except Exception:
frappe.log_error(frappe.get_traceback(), _("Plaid transactions sync error"))

View File

@@ -8,7 +8,6 @@ import json
from frappe import _
from frappe.model.document import Document
from frappe.utils import get_request_session
from requests.exceptions import HTTPError
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
from erpnext.erpnext_integrations.utils import get_webhook_address
from erpnext.erpnext_integrations.doctype.shopify_log.shopify_log import make_shopify_log
@@ -40,28 +39,24 @@ class ShopifySettings(Document):
def register_webhooks(self):
webhooks = ["orders/create", "orders/paid", "orders/fulfilled"]
url = get_shopify_url('admin/api/2020-04/webhooks.json', self)
url = get_shopify_url('admin/webhooks.json', self)
created_webhooks = [d.method for d in self.webhooks]
for method in webhooks:
if method in created_webhooks:
continue
session = get_request_session()
try:
res = session.post(url, data=json.dumps({
d = session.post(url, data=json.dumps({
"webhook": {
"topic": method,
"address": get_webhook_address(connector_name='shopify_connection', method='store_request_data'),
"format": "json"
}
}), headers=get_header(self))
res.raise_for_status()
self.update_webhook_table(method, res.json())
except HTTPError as e:
error_message = res.json().get('errors', e)
make_shopify_log(status="Warning", exception=error_message, rollback=True)
d.raise_for_status()
self.update_webhook_table(method, d.json())
except Exception as e:
make_shopify_log(status="Warning", message=e.message, exception=False)
@@ -70,18 +65,13 @@ class ShopifySettings(Document):
deleted_webhooks = []
for d in self.webhooks:
url = get_shopify_url('admin/api/2020-04/webhooks/{0}.json'.format(d.webhook_id), self)
url = get_shopify_url('admin/webhooks/{0}.json'.format(d.webhook_id), self)
try:
res = session.delete(url, headers=get_header(self))
res.raise_for_status()
deleted_webhooks.append(d)
except HTTPError as e:
error_message = res.json().get('errors', e)
make_shopify_log(status="Warning", exception=error_message, rollback=True)
except Exception as e:
frappe.log_error(message=e, title='Shopify Webhooks Issue')
frappe.log_error(message=frappe.get_traceback(), title=e.message[:140])
for d in deleted_webhooks:
self.remove(d)
@@ -154,3 +144,4 @@ def setup_custom_fields():
}
create_custom_fields(custom_fields)

View File

@@ -7,7 +7,7 @@ from erpnext.erpnext_integrations.doctype.shopify_settings.shopify_settings impo
shopify_variants_attr_list = ["option1", "option2", "option3"]
def sync_item_from_shopify(shopify_settings, item):
url = get_shopify_url("admin/api/2020-04/products/{0}.json".format(item.get("product_id")), shopify_settings)
url = get_shopify_url("/admin/products/{0}.json".format(item.get("product_id")), shopify_settings)
session = get_request_session()
try:

View File

@@ -386,5 +386,5 @@ def get_procedure_prescribed(patient):
return frappe.db.sql("""select pp.name, pp.procedure, pp.parent, ct.practitioner,
ct.encounter_date, pp.practitioner, pp.date, pp.department
from `tabPatient Encounter` ct, `tabProcedure Prescription` pp
where ct.patient=%(patient)s and pp.parent=ct.name and pp.appointment_booked=0
order by ct.creation desc""", {"patient": patient})
where ct.patient='{0}' and pp.parent=ct.name and pp.appointment_booked=0
order by ct.creation desc""".format(patient))

View File

@@ -48,17 +48,12 @@ def get_abbreviated_name(name, company):
@frappe.whitelist()
def get_children(doctype, parent=None, company=None, is_root=False):
condition = ''
var_dict = {
"name": get_root_of("Department"),
"parent": parent,
"company": company,
}
if company == parent:
condition = "name=%(name)s"
condition = "name='{0}'".format(get_root_of("Department"))
elif company:
condition = "parent_department=%(parent)s and company=%(company)s"
condition = "parent_department='{0}' and company='{1}'".format(parent, company)
else:
condition = "parent_department = %(parent)s"
condition = "parent_department = '{0}'".format(parent)
return frappe.db.sql("""
select
@@ -67,7 +62,7 @@ def get_children(doctype, parent=None, company=None, is_root=False):
from `tab{doctype}`
where
{condition}
order by name""".format(doctype=doctype, condition=condition), var_dict, as_dict=1)
order by name""".format(doctype=doctype, condition=condition), as_dict=1)
@frappe.whitelist()
def add_node():

View File

@@ -7,14 +7,6 @@ frappe.ui.form.on('Employee Onboarding', {
frm.add_fetch("employee_onboarding_template", "department", "department");
frm.add_fetch("employee_onboarding_template", "designation", "designation");
frm.add_fetch("employee_onboarding_template", "employee_grade", "employee_grade");
frm.set_query('job_offer', function () {
return {
filters: {
'job_applicant': frm.doc.job_applicant
}
};
});
},
refresh: function(frm) {

View File

@@ -496,7 +496,6 @@ erpnext.patches.v10_0.rename_offer_letter_to_job_offer
execute:frappe.delete_doc('DocType', 'Production Planning Tool', ignore_missing=True)
erpnext.patches.v10_0.migrate_daily_work_summary_settings_to_daily_work_summary_group # 24-12-2018
erpnext.patches.v10_0.add_default_cash_flow_mappers
erpnext.patches.v11_0.rename_duplicate_item_code_values
erpnext.patches.v11_0.make_quality_inspection_template
erpnext.patches.v10_0.update_status_for_multiple_source_in_po
erpnext.patches.v10_0.set_auto_created_serial_no_in_stock_entry

View File

@@ -1,8 +0,0 @@
import frappe
def execute():
items = []
items = frappe.db.sql("""select item_code from `tabItem` group by item_code having count(*) > 1""", as_dict=True)
if items:
for item in items:
frappe.db.sql("""update `tabItem` set item_code=name where item_code = %s""", (item.item_code))

View File

@@ -1,10 +1,9 @@
from __future__ import unicode_literals
from frappe import _
import frappe
def execute():
hr_settings = frappe.get_single("HR Settings")
hr_settings.leave_approval_notification_template = _("Leave Approval Notification")
hr_settings.leave_status_notification_template = _("Leave Status Notification")
hr_settings.save()
hr_settings.leave_approval_notification_template = "Leave Approval Notification"
hr_settings.leave_status_notification_template = "Leave Status Notification"
hr_settings.save()

View File

@@ -47,8 +47,8 @@ class Task(NestedSet):
def validate_status(self):
if self.status!=self.get_db_value("status") and self.status == "Closed":
for d in self.depends_on:
if frappe.db.get_value("Task", d.task, "status") not in ("Closed", "Cancelled"):
frappe.throw(_("Cannot close task as its dependant task {0} is not closed/cancelled.").format(d.task))
if frappe.db.get_value("Task", d.task, "status") != "Closed":
frappe.throw(_("Cannot close task as its dependant task {0} is not closed.").format(d.task))
from frappe.desk.form.assign_to import clear
clear(self.doctype, self.name)
@@ -199,10 +199,10 @@ def set_multiple_status(names, status):
task.save()
def set_tasks_as_overdue():
tasks = frappe.get_all("Task", filters={"status": ["not in", ["Cancelled", "Closed"]]}, fields=["name", "status", "review_date"])
tasks = frappe.get_all("Task", filters={'status':['not in',['Cancelled', 'Closed']]})
for task in tasks:
if task.status == "Pending Review":
if getdate(task.review_date) > getdate(today()):
if frappe.db.get_value("Task", task.name, "status") in 'Pending Review':
if getdate(frappe.db.get_value("Task", task.name, "review_date")) < getdate(today()):
continue
frappe.get_doc("Task", task.name).update_status()

View File

@@ -387,14 +387,9 @@ erpnext.taxes_and_totals = erpnext.payments.extend({
var diff = me.frm.doc.total + non_inclusive_tax_amount
- flt(last_tax.total, precision("grand_total"));
if(me.discount_amount_applied && me.frm.doc.discount_amount) {
diff -= flt(me.frm.doc.discount_amount);
}
diff = flt(diff, precision("rounding_adjustment"));
if ( diff && Math.abs(diff) <= (5.0 / Math.pow(10, precision("tax_amount", last_tax))) ) {
me.frm.doc.rounding_adjustment = diff;
this.frm.doc.rounding_adjustment = flt(flt(this.frm.doc.rounding_adjustment) + diff,
precision("rounding_adjustment"));
}
}
}

View File

@@ -853,19 +853,15 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
},
conversion_factor: function(doc, cdt, cdn, dont_fetch_price_list_rate) {
if(frappe.meta.get_docfield(cdt, "stock_qty", cdn)) {
if(doc.doctype != 'Material Request' && frappe.meta.get_docfield(cdt, "stock_qty", cdn)) {
var item = frappe.get_doc(cdt, cdn);
frappe.model.round_floats_in(item, ["qty", "conversion_factor"]);
item.stock_qty = flt(item.qty * item.conversion_factor, precision("stock_qty", item));
item.total_weight = flt(item.stock_qty * item.weight_per_unit);
refresh_field("stock_qty", item.name, item.parentfield);
refresh_field("total_weight", item.name, item.parentfield);
this.toggle_conversion_factor(item);
if(doc.doctype != "Material Request") {
item.total_weight = flt(item.stock_qty * item.weight_per_unit);
refresh_field("total_weight", item.name, item.parentfield);
this.calculate_net_weight();
}
this.calculate_net_weight();
if (!dont_fetch_price_list_rate &&
frappe.meta.has_field(doc.doctype, "price_list_currency")) {
this.apply_price_list(item, true);

View File

@@ -379,7 +379,7 @@ def get_gstins_for_company(company):
`tabDynamic Link`.parent = `tabAddress`.name and
`tabDynamic Link`.parenttype = 'Address' and
`tabDynamic Link`.link_doctype = 'Company' and
`tabDynamic Link`.link_name = %(company)s""", {"company": company})
`tabDynamic Link`.link_name = '{0}'""".format(company))
return company_gstins
def get_address_details(data, doc, company_address, billing_address):

View File

@@ -1687,7 +1687,7 @@
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "other_charges_calculation",
"fieldtype": "Long Text",
"fieldtype": "Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -3224,7 +3224,7 @@
"istable": 0,
"max_attachments": 1,
"menu_index": 0,
"modified": "2020-04-16 19:05:32.197858",
"modified": "2019-06-25 15:31:04.724730",
"modified_by": "Administrator",
"module": "Selling",
"name": "Quotation",

View File

@@ -1981,7 +1981,7 @@
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "other_charges_calculation",
"fieldtype": "Long Text",
"fieldtype": "Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -4204,7 +4204,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2020-04-16 19:05:14.867404",
"modified": "2019-04-05 03:44:46.037178",
"modified_by": "Administrator",
"module": "Selling",
"name": "Sales Order",

View File

@@ -622,6 +622,7 @@ def make_sales_invoice(source_name, target_doc=None, ignore_permissions=False):
target.set_advances()
def set_missing_values(source, target):
target.is_pos = 0
target.ignore_pricing_rule = 1
target.flags.ignore_permissions = True
target.run_method("set_missing_values")

View File

@@ -109,7 +109,7 @@ def get_product_list_for_group(product_group=None, start=0, limit=10, search=Non
or I.name like %(search)s)"""
search = "%" + cstr(search) + "%"
query += """order by I.weightage desc, in_stock desc, I.modified desc limit %s, %s""" % (cint(start), cint(limit))
query += """order by I.weightage desc, in_stock desc, I.modified desc limit %s, %s""" % (start, limit)
data = frappe.db.sql(query, {"product_group": product_group,"search": search, "today": nowdate()}, as_dict=1)
data = adjust_qty_for_expired_items(data)

View File

@@ -141,6 +141,6 @@ def insert_record(records):
raise
def welcome_email():
site_name = get_default_company() or "ERPNext"
title = _("Welcome to {0}").format(site_name)
return title
site_name = get_default_company()
title = _("Welcome to {0}".format(site_name))
return title

View File

@@ -48,7 +48,7 @@ def get_product_info_for_website(item_code):
def set_product_info_for_website(item):
"""set product price uom for website"""
product_info = get_product_info_for_website(item.item_code).get("product_info")
product_info = get_product_info_for_website(item.item_code)
if product_info:
item.update(product_info)

View File

@@ -2156,7 +2156,7 @@
"collapsible": 0,
"columns": 0,
"fieldname": "other_charges_calculation",
"fieldtype": "Long Text",
"fieldtype": "Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -4296,7 +4296,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2020-04-16 19:05:56.439204",
"modified": "2019-01-07 16:51:52.357859",
"modified_by": "Administrator",
"module": "Stock",
"name": "Delivery Note",

View File

@@ -400,6 +400,7 @@ def make_sales_invoice(source_name, target_doc=None):
invoiced_qty_map = get_invoiced_qty_map(source_name)
def set_missing_values(source, target):
target.is_pos = 0
target.ignore_pricing_rule = 1
target.run_method("set_missing_values")
target.run_method("set_po_nos")

View File

@@ -518,7 +518,7 @@ class Item(WebsiteGenerator):
"""select parent from `tabItem Barcode` where barcode = %s and parent != %s""", (item_barcode.barcode, self.name))
if duplicate:
frappe.throw(_("Barcode {0} already used in Item {1}").format(
item_barcode.barcode, duplicate[0][0]))
item_barcode.barcode, duplicate[0][0]), frappe.DuplicateEntryError)
item_barcode.barcode_type = "" if item_barcode.barcode_type not in options else item_barcode.barcode_type
if item_barcode.barcode_type and item_barcode.barcode_type.upper() in ('EAN', 'UPC-A', 'EAN-13', 'EAN-8'):

View File

@@ -124,7 +124,7 @@ class LandedCostVoucher(Document):
# update stock & gl entries for submit state of PR
doc.docstatus = 1
doc.update_stock_ledger(allow_negative_stock=True, via_landed_cost_voucher=True)
doc.update_stock_ledger(via_landed_cost_voucher=True)
doc.make_gl_entries()
def update_rate_in_serial_no(self, receipt_document):

View File

@@ -217,19 +217,7 @@ frappe.ui.form.on('Material Request', {
make_purchase_order: function(frm) {
frappe.prompt(
{
label: __('For Default Supplier (optional)'),
fieldname:'default_supplier',
fieldtype: 'Link',
options: 'Supplier',
description: __('Select a Supplier from the Default Supplier List of the items below.'),
get_query: () => {
return {
query: "erpnext.stock.doctype.material_request.material_request.get_default_supplier_query",
filters: {'doc': frm.doc.name}
}
}
},
{fieldname:'default_supplier', label: __('For Default Supplier (optional)'), fieldtype: 'Link', options: 'Supplier'},
(values) => {
frappe.model.open_mapped_doc({
method: "erpnext.stock.doctype.material_request.material_request.make_purchase_order",
@@ -237,8 +225,7 @@ frappe.ui.form.on('Material Request', {
args: { default_supplier: values.default_supplier },
run_link_triggers: true
});
},
__('Enter Supplier')
}
)
},

View File

@@ -371,18 +371,6 @@ def get_material_requests_based_on_supplier(supplier):
material_requests = []
return material_requests, supplier_items
def get_default_supplier_query(doctype, txt, searchfield, start, page_len, filters):
doc = frappe.get_doc("Material Request", filters.get("doc"))
item_list = []
for d in doc.items:
item_list.append(d.item_code)
return frappe.db.sql("""select default_supplier
from `tabItem Default`
where parent in ({0}) and
default_supplier IS NOT NULL
""".format(', '.join(['%s']*len(item_list))),tuple(item_list))
@frappe.whitelist()
def make_supplier_quotation(source_name, target_doc=None):
def postprocess(source, target_doc):

View File

@@ -1945,7 +1945,7 @@
"collapsible": 0,
"columns": 0,
"fieldname": "other_charges_calculation",
"fieldtype": "Long Text",
"fieldtype": "Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -3708,7 +3708,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2020-04-16 19:06:51.546358",
"modified": "2018-11-02 19:59:01.423485",
"modified_by": "Administrator",
"module": "Stock",
"name": "Purchase Receipt",

View File

@@ -348,7 +348,7 @@ class StockEntry(StockController):
elif d.t_warehouse and not d.basic_rate:
d.basic_rate = get_valuation_rate(d.item_code, d.t_warehouse,
self.doctype, d.name, d.allow_zero_valuation_rate,
currency=erpnext.get_company_currency(self.company), company=self.company)
currency=erpnext.get_company_currency(self.company))
def set_actual_qty(self):
allow_negative_stock = cint(frappe.db.get_value("Stock Settings", None, "allow_negative_stock"))

View File

@@ -3,15 +3,6 @@
frappe.ui.form.on('Stock Settings', {
refresh: function(frm) {
let filters = function() {
return {
filters : {
is_group : 0
}
};
};
frm.set_query("default_warehouse", filters);
frm.set_query("sample_retention_warehouse", filters);
}
});

View File

@@ -30,17 +30,9 @@ class StockSettings(Document):
frappe.make_property_setter({'fieldname': name, 'property': 'hidden',
'value': 0 if self.show_barcode_field else 1})
self.validate_warehouses()
self.cant_change_valuation_method()
self.validate_clean_description_html()
def validate_warehouses(self):
warehouse_fields = ["default_warehouse", "sample_retention_warehouse"]
for field in warehouse_fields:
if frappe.db.get_value("Warehouse", self.get(field), "is_group"):
frappe.throw(_("Group Warehouses cannot be used in transactions. Please change the value of {0}") \
.format(frappe.bold(self.meta.get_field(field).label)), title =_("Incorrect Warehouse"))
def cant_change_valuation_method(self):
db_valuation_method = frappe.db.get_single_value("Stock Settings", "valuation_method")

View File

@@ -233,7 +233,7 @@ def get_item_details(items, sle, filters):
`tabItem` item
{cf_join}
where
item.name in ({item_codes})
item.name in ({item_codes}) and ifnull(item.disabled, 0) = 0
""".format(cf_field=cf_field, cf_join=cf_join, item_codes=item_codes), as_dict=1)
for item in res:

View File

@@ -1,11 +1,10 @@
frappe
Unidecode==1.1.1
PyGithub==1.45
googlemaps==4.2.0
python-stdnum==1.13
braintree==3.59.0;python_version<"3.6"
braintree==4.0.0;python_version>="3.6"
gocardless-pro==1.16.0
WooCommerce==2.1.1
pandas==0.24.2
plaid-python==3.7.0
unidecode
pygithub
googlemaps
python-stdnum
braintree
gocardless_pro
woocommerce
pandas
plaid-python