diff --git a/.travis.yml b/.travis.yml
index 365eb67f3dc..213445b806e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -77,5 +77,6 @@ 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
diff --git a/cypress.json b/cypress.json
deleted file mode 100644
index 2be29158592..00000000000
--- a/cypress.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "baseUrl": "http://test_site_ui:8000"
-}
\ No newline at end of file
diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json
deleted file mode 100644
index da18d9352a1..00000000000
--- a/cypress/fixtures/example.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "name": "Using fixtures to represent data",
- "email": "hello@cypress.io",
- "body": "Fixtures are a great way to mock data for responses to routes"
-}
\ No newline at end of file
diff --git a/cypress/integration/opportunity/lost_reason_detail.js b/cypress/integration/opportunity/lost_reason_detail.js
deleted file mode 100644
index 9cf204889d6..00000000000
--- a/cypress/integration/opportunity/lost_reason_detail.js
+++ /dev/null
@@ -1,31 +0,0 @@
-context('Form', () => {
- before(() => {
- cy.login('Administrator', 'qwe');
- cy.visit('/desk');
- });
-
- it('create a new opportunity', () => {
- cy.visit('/desk#Form/Opportunity/New Opportunity 1');
- cy.get('.page-title').should('contain', 'Not Saved');
- cy.fill_field('opportunity_from', 'Customer', 'Select');
- cy.fill_field('party_name', 'Test Customer', 'Link').blur();
- cy.get('.primary-action').click();
- cy.get('.page-title').should('contain', 'Open');
- cy.get('.form-inner-toolbar button:contains("Lost")').click({ force: true });
- cy.get('.modal input[data-fieldname="lost_reason"]').as('input');
- cy.get('@input').focus().type('Higher', { delay: 200 });
- cy.get('.modal .awesomplete ul')
- .should('be.visible')
- .get('li:contains("Higher Price")')
- .click({ force: true });
- cy.get('@input').focus().type('No Followup', { delay: 200 });
- cy.get('.modal .awesomplete ul')
- .should('be.visible')
- .get('li:contains("No Followup")')
- .click();
-
- cy.fill_field('detailed_reason', 'Test Detailed Reason', 'Text');
- cy.get('.modal button:contains("Declare Lost")').click({ force: true });
- cy.get('.page-title').should('contain', 'Lost');
- });
-});
diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js
deleted file mode 100644
index cd02c3bd7a8..00000000000
--- a/cypress/plugins/index.js
+++ /dev/null
@@ -1,17 +0,0 @@
-// ***********************************************************
-// This example plugins/index.js can be used to load plugins
-//
-// You can change the location of this file or turn off loading
-// the plugins file with the 'pluginsFile' configuration option.
-//
-// You can read more here:
-// https://on.cypress.io/plugins-guide
-// ***********************************************************
-
-// This function is called when a project is opened or re-opened (e.g. due to
-// the project's config changing)
-
-// module.exports = (on, config) => {
-// `on` is used to hook into various events Cypress emits
-// `config` is the resolved Cypress config
-// }
diff --git a/cypress/support/commands.js b/cypress/support/commands.js
deleted file mode 100644
index c1f5a772e2b..00000000000
--- a/cypress/support/commands.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// ***********************************************
-// This example commands.js shows you how to
-// create various custom commands and overwrite
-// existing commands.
-//
-// For more comprehensive examples of custom
-// commands please read more here:
-// https://on.cypress.io/custom-commands
-// ***********************************************
-//
-//
-// -- This is a parent command --
-// Cypress.Commands.add("login", (email, password) => { ... })
-//
-//
-// -- This is a child command --
-// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
-//
-//
-// -- This is a dual command --
-// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
-//
-//
-// -- This is will overwrite an existing command --
-// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
diff --git a/cypress/support/index.js b/cypress/support/index.js
deleted file mode 100644
index 872df2d5d60..00000000000
--- a/cypress/support/index.js
+++ /dev/null
@@ -1,22 +0,0 @@
-// ***********************************************************
-// This example support/index.js is processed and
-// loaded automatically before your test files.
-//
-// This is a great place to put global configuration and
-// behavior that modifies Cypress.
-//
-// You can change the location of this file or turn off
-// automatically serving support files with the
-// 'supportFile' configuration option.
-//
-// You can read more here:
-// https://on.cypress.io/configuration
-// ***********************************************************
-
-// import frappe commands
-import '../../../frappe/cypress/support/index';
-// Import commands.js using ES2015 syntax:
-import './commands';
-
-// Alternatively you can use CommonJS syntax:
-// require('./commands')
diff --git a/erpnext/accounts/dashboard_chart_source/account_balance_timeline/account_balance_timeline.py b/erpnext/accounts/dashboard_chart_source/account_balance_timeline/account_balance_timeline.py
index 43acded3a98..a9b3d7c4cc2 100644
--- a/erpnext/accounts/dashboard_chart_source/account_balance_timeline/account_balance_timeline.py
+++ b/erpnext/accounts/dashboard_chart_source/account_balance_timeline/account_balance_timeline.py
@@ -4,7 +4,7 @@
from __future__ import unicode_literals
import frappe, json
from frappe import _
-from frappe.utils import add_to_date, date_diff, getdate, nowdate, get_last_day, formatdate
+from frappe.utils import add_to_date, date_diff, getdate, nowdate, get_last_day, formatdate, get_link_to_form
from erpnext.accounts.report.general_ledger.general_ledger import execute
from frappe.core.page.dashboard.dashboard import cache_source, get_from_date_from_timespan
from frappe.desk.doctype.dashboard_chart.dashboard_chart import get_period_ending
@@ -30,8 +30,13 @@ def get(chart_name = None, chart = None, no_cache = None, from_date = None, to_d
account = filters.get("account")
company = filters.get("company")
- if not account and chart:
- frappe.throw(_("Account is not set for the dashboard chart {0}").format(chart))
+ if not account and chart_name:
+ frappe.throw(_("Account is not set for the dashboard chart {0}")
+ .format(get_link_to_form("Dashboard Chart", chart_name)))
+
+ if not frappe.db.exists("Account", account) and chart_name:
+ frappe.throw(_("Account {0} does not exists in the dashboard chart {1}")
+ .format(account, get_link_to_form("Dashboard Chart", chart_name)))
if not to_date:
to_date = nowdate()
diff --git a/erpnext/accounts/doctype/account/chart_of_accounts/verified/de_kontenplan_SKR04_with_account_number.json b/erpnext/accounts/doctype/account/chart_of_accounts/verified/de_kontenplan_SKR04_with_account_number.json
index adfa9f89e23..275374a4b70 100644
--- a/erpnext/accounts/doctype/account/chart_of_accounts/verified/de_kontenplan_SKR04_with_account_number.json
+++ b/erpnext/accounts/doctype/account/chart_of_accounts/verified/de_kontenplan_SKR04_with_account_number.json
@@ -406,11 +406,11 @@
"is_group": 1,
"Bewertungskorrektur zu Forderungen aus Lieferungen und Leistungen": {
"account_number": "9960"
- },
- "Debitoren": {
- "is_group": 1,
- "account_number": "10000"
- },
+ },
+ "Debitoren": {
+ "is_group": 1,
+ "account_number": "10000"
+ },
"Forderungen aus Lieferungen und Leistungen": {
"account_number": "1200",
"account_type": "Receivable"
@@ -663,16 +663,22 @@
"account_number": "1400"
},
"Abziehbare Vorsteuer 7 %": {
- "account_number": "1401"
+ "account_number": "1401",
+ "account_type": "Tax",
+ "tax_rate": 7.0
},
"Abziehbare Vorsteuer aus innergem. Erwerb": {
"account_number": "1402"
},
"Abziehbare Vorsteuer aus innergem. Erwerb 19%": {
- "account_number": "1404"
+ "account_number": "1404",
+ "account_type": "Tax",
+ "tax_rate": 19.0
},
"Abziehbare Vorsteuer 19 %": {
- "account_number": "1406"
+ "account_number": "1406",
+ "account_type": "Tax",
+ "tax_rate": 19.0
},
"Abziehbare Vorsteuer nach \u00a7 13b UStG 19 %": {
"account_number": "1407"
@@ -1197,15 +1203,15 @@
"is_group": 1,
"Bewertungskorrektur zu Verb. aus Lieferungen und Leistungen": {
"account_number": "9964"
- },
- "Kreditoren": {
- "account_number": "70000",
- "is_group": 1,
- "Wareneingangs-Verrechnungskonto" : {
- "account_number": "70001",
- "account_type": "Stock Received But Not Billed"
- }
- },
+ },
+ "Kreditoren": {
+ "account_number": "70000",
+ "is_group": 1,
+ "Wareneingangs-Verrechnungskonto" : {
+ "account_number": "70001",
+ "account_type": "Stock Received But Not Billed"
+ }
+ },
"Verb. aus Lieferungen und Leistungen": {
"account_number": "3300",
"account_type": "Payable"
@@ -1488,17 +1494,21 @@
},
"Umsatzsteuer 7 %": {
"account_number": "3801",
- "account_type": "Tax"
+ "account_type": "Tax",
+ "tax_rate": 7.0
},
"Umsatzsteuer aus innergem. Erwerb": {
"account_number": "3802"
},
"Umsatzsteuer aus innergem. Erwerb 19 %": {
- "account_number": "3804"
+ "account_number": "3804",
+ "account_type": "Tax",
+ "tax_rate": 19.0
},
"Umsatzsteuer 19 %": {
"account_number": "3806",
- "account_type": "Tax"
+ "account_type": "Tax",
+ "tax_rate": 19.0
},
"Umsatzsteuer aus im Inland steuerpfl. EU-Lieferungen": {
"account_number": "3807"
@@ -2295,49 +2305,49 @@
},
"6 - sonstige betriebliche Ertr\u00e4ge": {
"root_type": "Income",
- "is_group": 1,
- "Erhaltene Boni (Gruppe)": {
- "is_group": 1,
- "Erhaltene Boni 7 % Vorsteuer": {
- "account_number": "5750"
- },
- "Erhaltene Boni aus Einkauf Roh-, Hilfs- und Betriebsstoffe": {
- "account_number": "5753"
- },
- "Erhaltene Boni aus Einkauf Roh-, Hilfs- und Betriebsstoffe 7% Vorsteuer": {
- "account_number": "5754"
- },
- "Erhaltene Boni aus Einkauf Roh-, Hilfs- und Betriebsstoffe 19% Vorsteuer": {
- "account_number": "5755"
- },
- "Erhaltene Boni 19 % Vorsteuer": {
- "account_number": "5760"
- },
- "Erhaltene Boni": {
- "account_number": "5769"
- }
- },
- "Erhaltene Rabatte (Gruppe)": {
- "is_group": 1,
- "Erhaltene Rabatte": {
- "account_number": "5770"
- },
- "Erhaltene Rabatte 7 % Vorsteuer": {
- "account_number": "5780"
- },
- "Erhaltene Rabatte aus Einkauf Roh-, Hilfs- und Betriebsstoffe": {
- "account_number": "5783"
- },
- "Erhaltene Rabatte aus Einkauf Roh-, Hilfs- und Betriebsstoffe 7% Vorsteuer": {
- "account_number": "5784"
- },
- "Erhaltene Rabatte aus Einkauf Roh-, Hilfs- und Betriebsstoffe 19% Vorsteuer": {
- "account_number": "5785"
- },
- "Erhaltene Rabatte 19 % Vorsteuer": {
- "account_number": "5790"
- }
- },
+ "is_group": 1,
+ "Erhaltene Boni (Gruppe)": {
+ "is_group": 1,
+ "Erhaltene Boni 7 % Vorsteuer": {
+ "account_number": "5750"
+ },
+ "Erhaltene Boni aus Einkauf Roh-, Hilfs- und Betriebsstoffe": {
+ "account_number": "5753"
+ },
+ "Erhaltene Boni aus Einkauf Roh-, Hilfs- und Betriebsstoffe 7% Vorsteuer": {
+ "account_number": "5754"
+ },
+ "Erhaltene Boni aus Einkauf Roh-, Hilfs- und Betriebsstoffe 19% Vorsteuer": {
+ "account_number": "5755"
+ },
+ "Erhaltene Boni 19 % Vorsteuer": {
+ "account_number": "5760"
+ },
+ "Erhaltene Boni": {
+ "account_number": "5769"
+ }
+ },
+ "Erhaltene Rabatte (Gruppe)": {
+ "is_group": 1,
+ "Erhaltene Rabatte": {
+ "account_number": "5770"
+ },
+ "Erhaltene Rabatte 7 % Vorsteuer": {
+ "account_number": "5780"
+ },
+ "Erhaltene Rabatte aus Einkauf Roh-, Hilfs- und Betriebsstoffe": {
+ "account_number": "5783"
+ },
+ "Erhaltene Rabatte aus Einkauf Roh-, Hilfs- und Betriebsstoffe 7% Vorsteuer": {
+ "account_number": "5784"
+ },
+ "Erhaltene Rabatte aus Einkauf Roh-, Hilfs- und Betriebsstoffe 19% Vorsteuer": {
+ "account_number": "5785"
+ },
+ "Erhaltene Rabatte 19 % Vorsteuer": {
+ "account_number": "5790"
+ }
+ },
"Andere aktivierte Eigenleistungen": {
"account_number": "4820"
},
@@ -2660,8 +2670,8 @@
},
"7 - sonstige betriebliche Aufwendungen": {
"root_type": "Expense",
- "is_group": 1,
- "Erl\u00f6sschm\u00e4lerungen (Gruppe)": {
+ "is_group": 1,
+ "Erl\u00f6sschm\u00e4lerungen (Gruppe)": {
"is_group": 1,
"Erl\u00f6sschm\u00e4lerungen": {
"account_number": "4700"
@@ -2744,7 +2754,7 @@
"Gew\u00e4hrte Rabatte 19 % USt": {
"account_number": "4790"
}
- },
+ },
"Sonstige betriebliche Aufwendungen": {
"account_number": "6300"
},
diff --git a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py
index 522ed4ffa46..462d967d015 100644
--- a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py
+++ b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py
@@ -172,7 +172,7 @@ def get_doctypes_with_dimensions():
return doclist
def get_accounting_dimensions(as_list=True):
- accounting_dimensions = frappe.get_all("Accounting Dimension", fields=["label", "fieldname", "disabled"])
+ accounting_dimensions = frappe.get_all("Accounting Dimension", fields=["label", "fieldname", "disabled", "document_type"])
if as_list:
return [d.fieldname for d in accounting_dimensions]
@@ -186,6 +186,18 @@ def get_checks_for_pl_and_bs_accounts():
return dimensions
+def get_dimension_with_children(doctype, dimension):
+
+ if isinstance(dimension, list):
+ dimension = dimension[0]
+
+ all_dimensions = []
+ lft, rgt = frappe.db.get_value(doctype, dimension, ["lft", "rgt"])
+ children = frappe.get_all(doctype, filters={"lft": [">=", lft], "rgt": ["<=", rgt]})
+ all_dimensions += [c.name for c in children]
+
+ return all_dimensions
+
@frappe.whitelist()
def get_dimension_filters():
dimension_filters = frappe.db.sql("""
diff --git a/erpnext/accounts/doctype/accounts_settings/regional/united_states.js b/erpnext/accounts/doctype/accounts_settings/regional/united_states.js
new file mode 100644
index 00000000000..d47d6e58039
--- /dev/null
+++ b/erpnext/accounts/doctype/accounts_settings/regional/united_states.js
@@ -0,0 +1,8 @@
+
+frappe.ui.form.on('Accounts Settings', {
+ refresh: function(frm) {
+ frm.set_df_property("acc_frozen_upto", "label", "Books Closed Through");
+ frm.set_df_property("frozen_accounts_modifier", "label", "Role Allowed to Close Books & Make Changes to Closed Periods");
+ frm.set_df_property("credit_controller", "label", "Credit Manager");
+ }
+});
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.py b/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.py
index 9aa2ee271a4..f28a07431fe 100644
--- a/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.py
+++ b/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.py
@@ -6,6 +6,7 @@ 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):
@@ -22,5 +23,8 @@ 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]
diff --git a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py
index 8900767324c..48fd154a4db 100644
--- a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py
+++ b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py
@@ -38,7 +38,6 @@ class BankReconciliation(Document):
group by t2.account, t1.name
order by t1.posting_date ASC, t1.name DESC
""".format(condition=condition), {"account": self.account, "from": self.from_date, "to": self.to_date}, as_dict=1)
- condition = ''
if self.bank_account:
condition += 'and bank_account = %(bank_account)s'
diff --git a/erpnext/accounts/doctype/c_form/c_form.js b/erpnext/accounts/doctype/c_form/c_form.js
index 3d0fc0a42ce..846408ff244 100644
--- a/erpnext/accounts/doctype/c_form/c_form.js
+++ b/erpnext/accounts/doctype/c_form/c_form.js
@@ -32,10 +32,12 @@ frappe.ui.form.on('C-Form Invoice Detail', {
invoice_no(frm, cdt, cdn) {
let d = frappe.get_doc(cdt, cdn);
- frm.call('get_invoice_details', {
- invoice_no: d.invoice_no
- }).then(r => {
- frappe.model.set_value(cdt, cdn, r.message);
- });
+ if (d.invoice_no) {
+ frm.call('get_invoice_details', {
+ invoice_no: d.invoice_no
+ }).then(r => {
+ frappe.model.set_value(cdt, cdn, r.message);
+ });
+ }
}
});
diff --git a/erpnext/accounts/doctype/discounted_invoice/discounted_invoice.json b/erpnext/accounts/doctype/discounted_invoice/discounted_invoice.json
index 5c3519a1592..02b0c4d937b 100644
--- a/erpnext/accounts/doctype/discounted_invoice/discounted_invoice.json
+++ b/erpnext/accounts/doctype/discounted_invoice/discounted_invoice.json
@@ -18,7 +18,8 @@
"in_list_view": 1,
"label": "Invoice",
"options": "Sales Invoice",
- "reqd": 1
+ "reqd": 1,
+ "search_index": 1
},
{
"fetch_from": "sales_invoice.customer",
@@ -60,7 +61,7 @@
}
],
"istable": 1,
- "modified": "2019-09-26 11:05:36.016772",
+ "modified": "2020-02-20 16:16:20.724620",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Discounted Invoice",
diff --git a/erpnext/accounts/doctype/discounted_invoice/discounted_invoice.py b/erpnext/accounts/doctype/discounted_invoice/discounted_invoice.py
index 93dfcc14bda..109737f7276 100644
--- a/erpnext/accounts/doctype/discounted_invoice/discounted_invoice.py
+++ b/erpnext/accounts/doctype/discounted_invoice/discounted_invoice.py
@@ -7,4 +7,4 @@ from __future__ import unicode_literals
from frappe.model.document import Document
class DiscountedInvoice(Document):
- pass
+ pass
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py
index 041e419752b..512e348c8bf 100644
--- a/erpnext/accounts/doctype/gl_entry/gl_entry.py
+++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py
@@ -232,10 +232,13 @@ def update_outstanding_amt(account, party_type, party, against_voucher_type, aga
if bal < 0 and not on_cancel:
frappe.throw(_("Outstanding for {0} cannot be less than zero ({1})").format(against_voucher, fmt_money(bal)))
- # Update outstanding amt on against voucher
if against_voucher_type in ["Sales Invoice", "Purchase Invoice", "Fees"]:
ref_doc = frappe.get_doc(against_voucher_type, against_voucher)
- ref_doc.db_set('outstanding_amount', bal)
+
+ # Didn't use db_set for optimisation purpose
+ ref_doc.outstanding_amount = bal
+ frappe.db.set_value(against_voucher_type, against_voucher, 'outstanding_amount', bal)
+
ref_doc.set_status(update=True)
def validate_frozen_account(account, adv_adj=None):
@@ -274,6 +277,9 @@ def update_against_account(voucher_type, voucher_no):
if d.against != new_against:
frappe.db.set_value("GL Entry", d.name, "against", new_against)
+def on_doctype_update():
+ frappe.db.add_index("GL Entry", ["against_voucher_type", "against_voucher"])
+ frappe.db.add_index("GL Entry", ["voucher_type", "voucher_no"])
def rename_gle_sle_docs():
for doctype in ["GL Entry", "Stock Ledger Entry"]:
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py
index 428b9acd150..04c5c9ec679 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py
@@ -459,8 +459,7 @@ class JournalEntry(AccountsController):
for d in self.get('accounts'):
if d.party_type in ['Customer', 'Supplier'] and d.party:
if not pay_to_recd_from:
- pay_to_recd_from = frappe.db.get_value(d.party_type, d.party,
- "customer_name" if d.party_type=="Customer" else "supplier_name")
+ pay_to_recd_from = d.party
if pay_to_recd_from and pay_to_recd_from == d.party:
party_amount += (d.debit_in_account_currency or d.credit_in_account_currency)
@@ -471,7 +470,8 @@ class JournalEntry(AccountsController):
bank_account_currency = d.account_currency
if pay_to_recd_from:
- self.pay_to_recd_from = pay_to_recd_from
+ self.pay_to_recd_from = frappe.db.get_value(d.party_type, pay_to_recd_from,
+ "customer_name" if d.party_type=="Customer" else "supplier_name")
if bank_amount:
total_amount = bank_amount
currency = bank_account_currency
diff --git a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
index a7ab1754bfc..a25e0e32c86 100644
--- a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
@@ -149,6 +149,49 @@ class TestPaymentEntry(unittest.TestCase):
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", pi.name, "outstanding_amount"))
self.assertEqual(outstanding_amount, 0)
+
+ def test_payment_against_sales_invoice_to_check_status(self):
+ si = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
+ currency="USD", conversion_rate=50)
+
+ pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank USD - _TC")
+ pe.reference_no = "1"
+ pe.reference_date = "2016-01-01"
+ pe.target_exchange_rate = 50
+ pe.insert()
+ pe.submit()
+
+ outstanding_amount, status = frappe.db.get_value("Sales Invoice", si.name, ["outstanding_amount", "status"])
+ self.assertEqual(flt(outstanding_amount), 0)
+ self.assertEqual(status, 'Paid')
+
+ pe.cancel()
+
+ outstanding_amount, status = frappe.db.get_value("Sales Invoice", si.name, ["outstanding_amount", "status"])
+ self.assertEqual(flt(outstanding_amount), 100)
+ self.assertEqual(status, 'Unpaid')
+
+ def test_payment_against_purchase_invoice_to_check_status(self):
+ pi = make_purchase_invoice(supplier="_Test Supplier USD", debit_to="_Test Payable USD - _TC",
+ currency="USD", conversion_rate=50)
+
+ pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank USD - _TC")
+ pe.reference_no = "1"
+ pe.reference_date = "2016-01-01"
+ pe.source_exchange_rate = 50
+ pe.insert()
+ pe.submit()
+
+ outstanding_amount, status = frappe.db.get_value("Purchase Invoice", pi.name, ["outstanding_amount", "status"])
+ self.assertEqual(flt(outstanding_amount), 0)
+ self.assertEqual(status, 'Paid')
+
+ pe.cancel()
+
+ outstanding_amount, status = frappe.db.get_value("Purchase Invoice", pi.name, ["outstanding_amount", "status"])
+ self.assertEqual(flt(outstanding_amount), 250)
+ self.assertEqual(status, 'Unpaid')
+
def test_payment_entry_against_ec(self):
payable = frappe.get_cached_value('Company', "_Test Company", 'default_payable_account')
@@ -566,4 +609,4 @@ class TestPaymentEntry(unittest.TestCase):
self.assertEqual(expected_party_account_balance, party_account_balance)
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
- accounts_settings.save()
+ accounts_settings.save()
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
index 2c04a27b0cd..30804961861 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
+++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
@@ -92,6 +92,7 @@ class PaymentReconciliation(Document):
FROM `tab{doc}`, `tabGL Entry`
WHERE
(`tab{doc}`.name = `tabGL Entry`.against_voucher or `tab{doc}`.name = `tabGL Entry`.voucher_no)
+ and `tab{doc}`.{party_type_field} = %(party)s
and `tab{doc}`.is_return = 1 and `tab{doc}`.return_against IS NULL
and `tabGL Entry`.against_voucher_type = %(voucher_type)s
and `tab{doc}`.docstatus = 1 and `tabGL Entry`.party = %(party)s
@@ -99,12 +100,17 @@ class PaymentReconciliation(Document):
GROUP BY `tab{doc}`.name
Having
amount > 0
- """.format(doc=voucher_type, dr_or_cr=dr_or_cr, reconciled_dr_or_cr=reconciled_dr_or_cr), {
- 'party': self.party,
- 'party_type': self.party_type,
- 'voucher_type': voucher_type,
- 'account': self.receivable_payable_account
- }, as_dict=1)
+ """.format(
+ doc=voucher_type,
+ dr_or_cr=dr_or_cr,
+ reconciled_dr_or_cr=reconciled_dr_or_cr,
+ party_type_field=frappe.scrub(self.party_type)),
+ {
+ 'party': self.party,
+ 'party_type': self.party_type,
+ 'voucher_type': voucher_type,
+ 'account': self.receivable_payable_account
+ }, as_dict=1)
def add_payment_entries(self, entries):
self.set('payments', [])
diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py
index 1aff43c7177..6b74f477f2b 100644
--- a/erpnext/accounts/doctype/payment_request/payment_request.py
+++ b/erpnext/accounts/doctype/payment_request/payment_request.py
@@ -126,12 +126,12 @@ class PaymentRequest(Document):
return controller.get_payment_url(**{
"amount": flt(self.grand_total, self.precision("grand_total")),
- "title": data.company.encode("utf-8"),
- "description": self.subject.encode("utf-8"),
+ "title": frappe.as_unicode(data.company),
+ "description": frappe.as_unicode(self.subject),
"reference_doctype": "Payment Request",
"reference_docname": self.name,
"payer_email": self.email_to or frappe.session.user,
- "payer_name": frappe.safe_encode(data.customer_name),
+ "payer_name": frappe.as_unicode(data.customer_name),
"order_id": self.name,
"currency": self.currency
})
@@ -475,4 +475,4 @@ def make_payment_order(source_name, target_doc=None):
}
}, target_doc, set_missing_values)
- return doclist
\ No newline at end of file
+ return doclist
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
index 1d8d9dbcef5..fc0d8b16f71 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
@@ -252,7 +252,7 @@ def get_pricing_rule_for_item(args, price_list_rate=0, doc=None, for_validate=Fa
if pricing_rule.price_or_product_discount == "Price":
apply_price_discount_rule(pricing_rule, item_details, args)
else:
- get_product_discount_rule(pricing_rule, item_details, doc)
+ get_product_discount_rule(pricing_rule, item_details, args, doc)
item_details.has_pricing_rule = 1
diff --git a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
index 9c1fef69fac..2da71dfd0e0 100644
--- a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
@@ -326,6 +326,66 @@ class TestPricingRule(unittest.TestCase):
self.assertEquals(item.discount_amount, 110)
self.assertEquals(item.rate, 990)
+ def test_pricing_rule_for_product_discount_on_same_item(self):
+ frappe.delete_doc_if_exists('Pricing Rule', '_Test Pricing Rule')
+ test_record = {
+ "doctype": "Pricing Rule",
+ "title": "_Test Pricing Rule",
+ "apply_on": "Item Code",
+ "currency": "USD",
+ "items": [{
+ "item_code": "_Test Item",
+ }],
+ "selling": 1,
+ "rate_or_discount": "Discount Percentage",
+ "rate": 0,
+ "min_qty": 0,
+ "max_qty": 7,
+ "discount_percentage": 17.5,
+ "price_or_product_discount": "Product",
+ "same_item": 1,
+ "free_qty": 1,
+ "company": "_Test Company"
+ }
+ frappe.get_doc(test_record.copy()).insert()
+
+ # With pricing rule
+ so = make_sales_order(item_code="_Test Item", qty=1)
+ so.load_from_db()
+ self.assertEqual(so.items[1].is_free_item, 1)
+ self.assertEqual(so.items[1].item_code, "_Test Item")
+
+
+ def test_pricing_rule_for_product_discount_on_different_item(self):
+ frappe.delete_doc_if_exists('Pricing Rule', '_Test Pricing Rule')
+ test_record = {
+ "doctype": "Pricing Rule",
+ "title": "_Test Pricing Rule",
+ "apply_on": "Item Code",
+ "currency": "USD",
+ "items": [{
+ "item_code": "_Test Item",
+ }],
+ "selling": 1,
+ "rate_or_discount": "Discount Percentage",
+ "rate": 0,
+ "min_qty": 0,
+ "max_qty": 7,
+ "discount_percentage": 17.5,
+ "price_or_product_discount": "Product",
+ "same_item": 0,
+ "free_item": "_Test Item 2",
+ "free_qty": 1,
+ "company": "_Test Company"
+ }
+ frappe.get_doc(test_record.copy()).insert()
+
+ # With pricing rule
+ so = make_sales_order(item_code="_Test Item", qty=1)
+ so.load_from_db()
+ self.assertEqual(so.items[1].is_free_item, 1)
+ self.assertEqual(so.items[1].item_code, "_Test Item 2")
+
def make_pricing_rule(**args):
args = frappe._dict(args)
diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py
index e475563c77c..2ffa27f6d99 100644
--- a/erpnext/accounts/doctype/pricing_rule/utils.py
+++ b/erpnext/accounts/doctype/pricing_rule/utils.py
@@ -245,7 +245,7 @@ def filter_pricing_rules(args, pricing_rules, doc=None):
def validate_quantity_and_amount_for_suggestion(args, qty, amount, item_code, transaction_type):
fieldname, msg = '', ''
- type_of_transaction = 'purcahse' if transaction_type == "buying" else "sale"
+ type_of_transaction = 'purchase' if transaction_type == 'buying' else 'sale'
for field, value in {'min_qty': qty, 'min_amt': amount}.items():
if (args.get(field) and value < args.get(field)
@@ -435,7 +435,7 @@ def apply_pricing_rule_on_transaction(doc):
doc.calculate_taxes_and_totals()
elif d.price_or_product_discount == 'Product':
item_details = frappe._dict({'parenttype': doc.doctype})
- get_product_discount_rule(d, item_details, doc)
+ get_product_discount_rule(d, item_details, doc=doc)
apply_pricing_rule_for_free_items(doc, item_details.free_item_data)
doc.set_missing_values()
@@ -443,9 +443,10 @@ def get_applied_pricing_rules(item_row):
return (item_row.get("pricing_rules").split(',')
if item_row.get("pricing_rules") else [])
-def get_product_discount_rule(pricing_rule, item_details, doc=None):
- free_item = (pricing_rule.free_item
- if not pricing_rule.same_item or pricing_rule.apply_on == 'Transaction' else item_details.item_code)
+def get_product_discount_rule(pricing_rule, item_details, args=None, doc=None):
+ free_item = pricing_rule.free_item
+ if pricing_rule.same_item:
+ free_item = item_details.item_code or args.item_code
if not free_item:
frappe.throw(_("Free item not set in the pricing rule {0}")
@@ -464,7 +465,7 @@ def get_product_discount_rule(pricing_rule, item_details, doc=None):
item_details.free_item_data.update(item_data)
item_details.free_item_data['uom'] = pricing_rule.free_item_uom or item_data.stock_uom
- item_details.free_item_data['conversion_factor'] = get_conversion_factor(free_item,
+ item_details.free_item_data['conversion_factor'] = get_conversion_factor(free_item,
item_details.free_item_data['uom']).get("conversion_factor", 1)
if item_details.get("parenttype") == 'Purchase Order':
@@ -507,7 +508,7 @@ def validate_coupon_code(coupon_name):
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"))
+ frappe.throw(_("Sorry,coupon code validity has expired"))
elif coupon.used>=coupon.maximum_use:
frappe.throw(_("Sorry,coupon code are exhausted"))
else:
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 737c18a8a98..698c2ab333d 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -368,7 +368,7 @@ class PurchaseInvoice(BuyingController):
update_outstanding_amt(self.credit_to, "Supplier", self.supplier,
self.doctype, self.return_against if cint(self.is_return) and self.return_against else self.name)
- if repost_future_gle and cint(self.update_stock) and self.auto_accounting_for_stock:
+ if (repost_future_gle or self.flags.repost_future_gle) and cint(self.update_stock) and self.auto_accounting_for_stock:
from erpnext.controllers.stock_controller import update_gl_entries_after
items, warehouses = self.get_items_and_warehouses()
update_gl_entries_after(self.posting_date, self.posting_time,
@@ -1024,3 +1024,6 @@ def block_invoice(name, release_date, hold_comment=None):
def make_inter_company_sales_invoice(source_name, target_doc=None):
from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_inter_company_transaction
return make_inter_company_transaction("Purchase Invoice", source_name, target_doc)
+
+def on_doctype_update():
+ frappe.db.add_index("Purchase Invoice", ["supplier", "is_return", "return_against"])
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
index acb0398b5c0..36bb2be3dc5 100644
--- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
+++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
@@ -198,7 +198,6 @@
"fieldtype": "Link",
"label": "UOM",
"options": "UOM",
- "print_hide": 1,
"reqd": 1
},
{
@@ -771,7 +770,7 @@
"idx": 1,
"istable": 1,
"links": [],
- "modified": "2019-12-04 12:23:17.046413",
+ "modified": "2020-03-05 14:20:17.297284",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice Item",
diff --git a/erpnext/accounts/doctype/sales_invoice/pos.py b/erpnext/accounts/doctype/sales_invoice/pos.py
index 749816f7814..16e918cc728 100755
--- a/erpnext/accounts/doctype/sales_invoice/pos.py
+++ b/erpnext/accounts/doctype/sales_invoice/pos.py
@@ -207,7 +207,7 @@ def get_customers_list(pos_profile={}):
if pos_profile.get('customer_groups'):
# Get customers based on the customer groups defined in the POS profile
for d in pos_profile.get('customer_groups'):
- customer_groups.extend([d.name for d in get_child_nodes('Customer Group', d.customer_group)])
+ customer_groups.extend([d.get('name') for d in get_child_nodes('Customer Group', d.get('customer_group'))])
cond = "customer_group in (%s)" % (', '.join(['%s'] * len(customer_groups)))
return frappe.db.sql(""" select name, customer_name, customer_group,
@@ -387,7 +387,9 @@ def get_pricing_rule_data(doc):
@frappe.whitelist()
-def make_invoice(doc_list={}, email_queue_list={}, customers_list={}):
+def make_invoice(pos_profile, doc_list={}, email_queue_list={}, customers_list={}):
+ import json
+
if isinstance(doc_list, string_types):
doc_list = json.loads(doc_list)
@@ -421,7 +423,11 @@ def make_invoice(doc_list={}, email_queue_list={}, customers_list={}):
name_list.append(name)
email_queue = make_email_queue(email_queue_list)
- customers = get_customers_list()
+
+ if isinstance(pos_profile, string_types):
+ pos_profile = json.loads(pos_profile)
+
+ customers = get_customers_list(pos_profile)
return {
'invoice': name_list,
'email_queue': email_queue,
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 0dc889c0b7a..fcddab40b8f 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -717,7 +717,7 @@ class SalesInvoice(SellingController):
update_outstanding_amt(self.debit_to, "Customer", self.customer,
self.doctype, self.return_against if cint(self.is_return) and self.return_against else self.name)
- if repost_future_gle and cint(self.update_stock) \
+ if (repost_future_gle or self.flags.repost_future_gle) and cint(self.update_stock) \
and cint(auto_accounting_for_stock):
items, warehouses = self.get_items_and_warehouses()
update_gl_entries_after(self.posting_date, self.posting_time,
@@ -1211,24 +1211,6 @@ class SalesInvoice(SellingController):
self.set_missing_values(for_validate = True)
- def get_discounting_status(self):
- status = None
- if self.is_discounted:
- invoice_discounting_list = frappe.db.sql("""
- select status
- from `tabInvoice Discounting` id, `tabDiscounted Invoice` d
- where
- id.name = d.parent
- and d.sales_invoice=%s
- and id.docstatus=1
- and status in ('Disbursed', 'Settled')
- """, self.name)
- for d in invoice_discounting_list:
- status = d[0]
- if status == "Disbursed":
- break
- return status
-
def set_status(self, update=False, status=None, update_modified=True):
if self.is_new():
if self.get('amended_from'):
@@ -1237,25 +1219,31 @@ class SalesInvoice(SellingController):
precision = self.precision("outstanding_amount")
outstanding_amount = flt(self.outstanding_amount, precision)
+ due_date = getdate(self.due_date)
+ nowdate = getdate()
+
+ discounting_status = None
+ if self.is_discounted:
+ discountng_status = get_discounting_status(self.name)
if not status:
if self.docstatus == 2:
status = "Cancelled"
elif self.docstatus == 1:
- if outstanding_amount > 0 and getdate(self.due_date) < getdate(nowdate()) and self.is_discounted and self.get_discounting_status()=='Disbursed':
+ if outstanding_amount > 0 and due_date < nowdate and self.is_discounted and discountng_status=='Disbursed':
self.status = "Overdue and Discounted"
- elif outstanding_amount > 0 and getdate(self.due_date) < getdate(nowdate()):
+ elif outstanding_amount > 0 and due_date < nowdate:
self.status = "Overdue"
- elif outstanding_amount > 0 and getdate(self.due_date) >= getdate(nowdate()) and self.is_discounted and self.get_discounting_status()=='Disbursed':
+ elif outstanding_amount > 0 and due_date >= nowdate and self.is_discounted and discountng_status=='Disbursed':
self.status = "Unpaid and Discounted"
- elif outstanding_amount > 0 and getdate(self.due_date) >= getdate(nowdate()):
+ elif outstanding_amount > 0 and due_date >= nowdate:
self.status = "Unpaid"
#Check if outstanding amount is 0 due to credit note issued against invoice
elif outstanding_amount <= 0 and self.is_return == 0 and frappe.db.get_value('Sales Invoice', {'is_return': 1, 'return_against': self.name, 'docstatus': 1}):
self.status = "Credit Note Issued"
elif self.is_return == 1:
self.status = "Return"
- elif outstanding_amount <=0:
+ elif outstanding_amount<=0:
self.status = "Paid"
else:
self.status = "Submitted"
@@ -1265,6 +1253,26 @@ class SalesInvoice(SellingController):
if update:
self.db_set('status', self.status, update_modified = update_modified)
+def get_discounting_status(sales_invoice):
+ status = None
+
+ invoice_discounting_list = frappe.db.sql("""
+ select status
+ from `tabInvoice Discounting` id, `tabDiscounted Invoice` d
+ where
+ id.name = d.parent
+ and d.sales_invoice=%s
+ and id.docstatus=1
+ and status in ('Disbursed', 'Settled')
+ """, sales_invoice)
+
+ for d in invoice_discounting_list:
+ status = d[0]
+ if status == "Disbursed":
+ break
+
+ return status
+
def validate_inter_company_party(doctype, party, company, inter_company_reference):
if not party:
return
@@ -1432,6 +1440,21 @@ def get_inter_company_details(doc, doctype):
"company": company
}
+def get_internal_party(parties, link_doctype, doc):
+ if len(parties) == 1:
+ party = parties[0].name
+ else:
+ # If more than one Internal Supplier/Customer, get supplier/customer on basis of address
+ if doc.get('company_address') or doc.get('shipping_address'):
+ party = frappe.db.get_value("Dynamic Link", {"parent": doc.get('company_address') or doc.get('shipping_address'),
+ "parenttype": "Address", "link_doctype": link_doctype}, "link_name")
+
+ if not party:
+ party = parties[0].name
+ else:
+ party = parties[0].name
+
+ return party
def validate_inter_company_transaction(doc, doctype):
@@ -1520,6 +1543,9 @@ def get_loyalty_programs(customer):
else:
return lp_details
+def on_doctype_update():
+ frappe.db.add_index("Sales Invoice", ["customer", "is_return", "return_against"])
+
@frappe.whitelist()
def create_invoice_discounting(source_name, target_doc=None):
invoice = frappe.get_doc("Sales Invoice", source_name)
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index a2a47b3a19c..267e52a477b 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -728,7 +728,7 @@ class TestSalesInvoice(unittest.TestCase):
def test_make_pos_invoice(self):
from erpnext.accounts.doctype.sales_invoice.pos import make_invoice
- make_pos_profile()
+ pos_profile = make_pos_profile()
pr = make_purchase_receipt(company= "_Test Company with perpetual inventory",supplier_warehouse= "Work In Progress - TCP1", item_code= "_Test FG Item",warehouse= "Stores - TCP1",cost_center= "Main - TCP1")
pos = create_sales_invoice(company= "_Test Company with perpetual inventory", debit_to="Debtors - TCP1", item_code= "_Test FG Item", warehouse="Stores - TCP1", income_account = "Sales - TCP1", expense_account = "Cost of Goods Sold - TCP1", cost_center = "Main - TCP1", do_not_save=True)
@@ -744,7 +744,7 @@ class TestSalesInvoice(unittest.TestCase):
pos.append("taxes", tax)
invoice_data = [{'09052016142': pos}]
- si = make_invoice(invoice_data).get('invoice')
+ si = make_invoice(pos_profile, invoice_data).get('invoice')
self.assertEqual(si[0], '09052016142')
sales_invoice = frappe.get_all('Sales Invoice', fields =["*"], filters = {'offline_pos_name': '09052016142', 'docstatus': 1})
@@ -762,7 +762,7 @@ class TestSalesInvoice(unittest.TestCase):
if allow_negative_stock:
frappe.db.set_value('Stock Settings', None, 'allow_negative_stock', 0)
- make_pos_profile()
+ pos_profile = make_pos_profile()
timestamp = cint(time.time())
item = make_item("_Test POS Item")
@@ -776,7 +776,7 @@ class TestSalesInvoice(unittest.TestCase):
{'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 330}]
invoice_data = [{timestamp: pos}]
- si = make_invoice(invoice_data).get('invoice')
+ si = make_invoice(pos_profile, invoice_data).get('invoice')
self.assertEqual(si[0], timestamp)
sales_invoice = frappe.get_all('Sales Invoice', fields =["*"], filters = {'offline_pos_name': timestamp})
@@ -785,7 +785,7 @@ class TestSalesInvoice(unittest.TestCase):
timestamp = cint(time.time())
pos["offline_pos_name"] = timestamp
invoice_data = [{timestamp: pos}]
- si1 = make_invoice(invoice_data).get('invoice')
+ si1 = make_invoice(pos_profile, invoice_data).get('invoice')
self.assertEqual(si1[0], timestamp)
sales_invoice1 = frappe.get_all('Sales Invoice', fields =["*"], filters = {'offline_pos_name': timestamp})
diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py
index bb1b7e392dc..5ba455c1315 100644
--- a/erpnext/accounts/general_ledger.py
+++ b/erpnext/accounts/general_ledger.py
@@ -136,12 +136,14 @@ def save_entries(gl_map, adv_adj, update_outstanding, from_repost=False):
def make_entry(args, adv_adj, update_outstanding, from_repost=False):
- args.update({"doctype": "GL Entry"})
- gle = frappe.get_doc(args)
+ gle = frappe.new_doc("GL Entry")
+ gle.update(args)
gle.flags.ignore_permissions = 1
gle.flags.from_repost = from_repost
- gle.insert()
+ gle.validate()
+ gle.db_insert()
gle.run_method("on_update_with_args", adv_adj, update_outstanding, from_repost)
+ gle.flags.ignore_validate = True
gle.submit()
def validate_account_for_perpetual_inventory(gl_map):
diff --git a/erpnext/accounts/page/pos/pos.js b/erpnext/accounts/page/pos/pos.js
index 8dc00f3f218..24fcb41a5db 100755
--- a/erpnext/accounts/page/pos/pos.js
+++ b/erpnext/accounts/page/pos/pos.js
@@ -1769,6 +1769,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
method: "erpnext.accounts.doctype.sales_invoice.pos.make_invoice",
freeze: true,
args: {
+ pos_profile: me.pos_profile_data,
doc_list: me.si_docs,
email_queue_list: me.email_queue_list,
customers_list: me.customers_list
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
index 0438f6d09e1..240b0d83817 100755
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
@@ -7,7 +7,7 @@ from frappe import _, scrub
from frappe.utils import getdate, nowdate, flt, cint, formatdate, cstr, now, time_diff_in_seconds
from collections import OrderedDict
from erpnext.accounts.utils import get_currency_precision
-from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
+from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions, get_dimension_with_children
# This report gives a summary of all Outstanding Invoices considering the following
@@ -603,7 +603,6 @@ class ReceivablePayableReport(object):
self.add_supplier_filters(conditions, values)
self.add_accounting_dimensions_filters(conditions, values)
-
return " and ".join(conditions), values
def get_order_by_condition(self):
@@ -666,13 +665,16 @@ class ReceivablePayableReport(object):
doctype=doctype, lft=lft, rgt=rgt, key=key)
def add_accounting_dimensions_filters(self, conditions, values):
- accounting_dimensions = get_accounting_dimensions()
+ accounting_dimensions = get_accounting_dimensions(as_list=False)
if accounting_dimensions:
for dimension in accounting_dimensions:
- if self.filters.get(dimension):
- conditions.append("{0} = %s".format(dimension))
- values.append(self.filters.get(dimension))
+ if self.filters.get(dimension.fieldname):
+ if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
+ self.filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
+ self.filters.get(dimension.fieldname))
+ conditions.append("{0} in %s".format(dimension.fieldname))
+ values.append(tuple(self.filters.get(dimension.fieldname)))
def get_gle_balance(self, gle):
# get the balance of the GL (debit - credit) or reverse balance based on report type
diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py
index 75433a135f3..2636a1d2efc 100644
--- a/erpnext/accounts/report/financial_statements.py
+++ b/erpnext/accounts/report/financial_statements.py
@@ -16,7 +16,7 @@ from frappe import _
from frappe.utils import (flt, getdate, get_first_day, add_months, add_days, formatdate, cstr)
from six import itervalues
-from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
+from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions, get_dimension_with_children
def get_period_list(from_fiscal_year, to_fiscal_year, periodicity, accumulated_values=False,
company=None, reset_period_on_fy_change=True):
@@ -389,7 +389,7 @@ def set_gl_entries_by_account(
def get_additional_conditions(from_date, ignore_closing_entries, filters):
additional_conditions = []
- accounting_dimensions = get_accounting_dimensions()
+ accounting_dimensions = get_accounting_dimensions(as_list=False)
if ignore_closing_entries:
additional_conditions.append("ifnull(voucher_type, '')!='Period Closing Voucher'")
@@ -412,11 +412,14 @@ def get_additional_conditions(from_date, ignore_closing_entries, filters):
additional_conditions.append("(finance_book in (%(finance_book)s, %(company_fb)s, '') OR finance_book IS NULL)")
else:
additional_conditions.append("(finance_book in (%(finance_book)s, '') OR finance_book IS NULL)")
-
+
if accounting_dimensions:
for dimension in accounting_dimensions:
- if filters.get(dimension):
- additional_conditions.append("{0} in (%({0})s)".format(dimension))
+ if filters.get(dimension.fieldname):
+ if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
+ filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
+ filters.get(dimension.fieldname))
+ additional_conditions.append("{0} in %({0})s".format(dimension.fieldname))
return " and {}".format(" and ".join(additional_conditions)) if additional_conditions else ""
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.html b/erpnext/accounts/report/general_ledger/general_ledger.html
index 40469aecc1d..9a2205a5791 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.html
+++ b/erpnext/accounts/report/general_ledger/general_ledger.html
@@ -2,7 +2,7 @@
{% if (filters.party_name) { %}
{%= filters.party_name %}
- {% } else if (filters.party && filters.show_name) { %}
+ {% } else if (filters.party) { %}
{%= filters.party %}
{% } else if (filters.account) { %}
{%= filters.account %}
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py
index 0939354efa7..f45911f90e5 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.py
+++ b/erpnext/accounts/report/general_ledger/general_ledger.py
@@ -10,7 +10,7 @@ from frappe import _, _dict
from erpnext.accounts.utils import get_account_currency
from erpnext.accounts.report.financial_statements import get_cost_centers_with_children
from six import iteritems
-from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
+from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions, get_dimension_with_children
from collections import OrderedDict
def execute(filters=None):
@@ -194,12 +194,15 @@ def get_conditions(filters):
if match_conditions:
conditions.append(match_conditions)
- accounting_dimensions = get_accounting_dimensions()
+ accounting_dimensions = get_accounting_dimensions(as_list=False)
if accounting_dimensions:
for dimension in accounting_dimensions:
- if filters.get(dimension):
- conditions.append("{0} in (%({0})s)".format(dimension))
+ if filters.get(dimension.fieldname):
+ if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
+ filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
+ filters.get(dimension.fieldname))
+ conditions.append("{0} in %({0})s".format(dimension.fieldname))
return "and {}".format(" and ".join(conditions)) if conditions else ""
diff --git a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
index 4523f66deb4..127f3133f5b 100644
--- a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
+++ b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
@@ -54,8 +54,8 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
'description': d.description,
'invoice': d.parent,
'posting_date': d.posting_date,
- 'customer': d.supplier,
- 'customer_name': d.supplier_name
+ 'supplier': d.supplier,
+ 'supplier_name': d.supplier_name
}
if additional_query_columns:
@@ -201,7 +201,8 @@ def get_columns(additional_table_columns, filters):
{
'label': _('Mode Of Payment'),
'fieldname': 'mode_of_payment',
- 'fieldtype': 'Data',
+ 'fieldtype': 'Link',
+ 'options': 'Mode of Payment',
'width': 120
},
{
@@ -309,6 +310,8 @@ def get_items(filters, additional_query_columns):
if additional_query_columns:
additional_query_columns = ', ' + ', '.join(additional_query_columns)
+ else:
+ additional_query_columns = ''
return frappe.db.sql("""
select
@@ -320,7 +323,7 @@ def get_items(filters, additional_query_columns):
`tabPurchase Invoice Item`.`purchase_receipt`, `tabPurchase Invoice Item`.`po_detail`,
`tabPurchase Invoice Item`.`expense_account`, `tabPurchase Invoice Item`.`stock_qty`,
`tabPurchase Invoice Item`.`stock_uom`, `tabPurchase Invoice Item`.`base_net_amount`,
- `tabPurchase Invoice`.supplier_name, `tabPurchase Invoice`.mode_of_payment {0}
+ `tabPurchase Invoice`.`supplier_name`, `tabPurchase Invoice`.`mode_of_payment` {0}
from `tabPurchase Invoice`, `tabPurchase Invoice Item`
where `tabPurchase Invoice`.name = `tabPurchase Invoice Item`.`parent` and
`tabPurchase Invoice`.docstatus = 1 %s
diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py
index 786e04dd5aa..0c8957ae441 100644
--- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py
+++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py
@@ -373,6 +373,8 @@ def get_items(filters, additional_query_columns):
if additional_query_columns:
additional_query_columns = ', ' + ', '.join(additional_query_columns)
+ else:
+ additional_query_columns = ''
return frappe.db.sql("""
select
diff --git a/erpnext/accounts/report/sales_register/sales_register.py b/erpnext/accounts/report/sales_register/sales_register.py
index 2be90bc5264..9864e40c1a9 100644
--- a/erpnext/accounts/report/sales_register/sales_register.py
+++ b/erpnext/accounts/report/sales_register/sales_register.py
@@ -6,7 +6,7 @@ import frappe
from frappe.utils import flt
from frappe import msgprint, _
from frappe.model.meta import get_field_precision
-from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
+from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions, get_dimension_with_children
def execute(filters=None):
return _execute(filters)
@@ -341,14 +341,18 @@ def get_conditions(filters):
where parent=`tabSales Invoice`.name
and ifnull(`tabSales Invoice Item`.item_group, '') = %(item_group)s)"""
- accounting_dimensions = get_accounting_dimensions()
+ accounting_dimensions = get_accounting_dimensions(as_list=False)
if accounting_dimensions:
for dimension in accounting_dimensions:
- if filters.get(dimension):
+ if filters.get(dimension.fieldname):
+ if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
+ filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
+ filters.get(dimension.fieldname))
+
conditions += """ and exists(select name from `tabSales Invoice Item`
where parent=`tabSales Invoice`.name
- and ifnull(`tabSales Invoice Item`.{0}, '') = %({0})s)""".format(dimension)
+ and ifnull(`tabSales Invoice Item`.{0}, '') in %({0})s)""".format(dimension.fieldname)
return conditions
diff --git a/erpnext/accounts/report/trial_balance/trial_balance.py b/erpnext/accounts/report/trial_balance/trial_balance.py
index 69285cc9634..5fe6b416fda 100644
--- a/erpnext/accounts/report/trial_balance/trial_balance.py
+++ b/erpnext/accounts/report/trial_balance/trial_balance.py
@@ -7,7 +7,7 @@ from frappe import _
from frappe.utils import flt, getdate, formatdate, cstr
from erpnext.accounts.report.financial_statements \
import filter_accounts, set_gl_entries_by_account, filter_out_zero_value_rows
-from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
+from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions, get_dimension_with_children
value_fields = ("opening_debit", "opening_credit", "debit", "credit", "closing_debit", "closing_credit")
@@ -109,7 +109,7 @@ def get_rootwise_opening_balances(filters, report_type):
additional_conditions += fb_conditions
- accounting_dimensions = get_accounting_dimensions()
+ accounting_dimensions = get_accounting_dimensions(as_list=False)
query_filters = {
"company": filters.company,
@@ -122,11 +122,14 @@ def get_rootwise_opening_balances(filters, report_type):
if accounting_dimensions:
for dimension in accounting_dimensions:
- if filters.get(dimension):
- additional_conditions += """ and {0} in (%({0})s) """.format(dimension)
+ if filters.get(dimension.fieldname):
+ if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
+ filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
+ filters.get(dimension.fieldname))
+ additional_conditions += "and {0} in %({0})s".format(dimension.fieldname)
query_filters.update({
- dimension: filters.get(dimension)
+ dimension.fieldname: filters.get(dimension.fieldname)
})
gle = frappe.db.sql("""
diff --git a/erpnext/config/accounts.py b/erpnext/config/accounts.py
index ab75f211c04..3df5fcc3ebd 100644
--- a/erpnext/config/accounts.py
+++ b/erpnext/config/accounts.py
@@ -181,6 +181,11 @@ def get_data():
"name": "Payment Reconciliation",
"description": _("Match non-linked Invoices and Payments.")
},
+ {
+ "type": "doctype",
+ "label": _("Invoice Discounting"),
+ "name": "Invoice Discounting",
+ },
{
"type": "doctype",
"label": _("Update Bank Transaction Dates"),
@@ -189,8 +194,9 @@ def get_data():
},
{
"type": "doctype",
- "label": _("Invoice Discounting"),
- "name": "Invoice Discounting",
+ "label": _("Bank Transaction"),
+ "name": "Bank Transaction",
+ "doctype": "Bank Transaction"
},
{
"type": "report",
diff --git a/erpnext/config/buying.py b/erpnext/config/buying.py
index 6f5ab32b631..1d4054786e6 100644
--- a/erpnext/config/buying.py
+++ b/erpnext/config/buying.py
@@ -7,6 +7,13 @@ def get_data():
"label": _("Purchasing"),
"icon": "fa fa-star",
"items": [
+ {
+ "type": "doctype",
+ "name": "Material Request",
+ "onboard": 1,
+ "dependencies": ["Item"],
+ "description": _("Request for purchase."),
+ },
{
"type": "doctype",
"name": "Purchase Order",
@@ -20,13 +27,6 @@ def get_data():
"onboard": 1,
"dependencies": ["Item", "Supplier"]
},
- {
- "type": "doctype",
- "name": "Material Request",
- "onboard": 1,
- "dependencies": ["Item"],
- "description": _("Request for purchase."),
- },
{
"type": "doctype",
"name": "Request for Quotation",
@@ -63,6 +63,11 @@ def get_data():
"name": "Price List",
"description": _("Price List master.")
},
+ {
+ "type": "doctype",
+ "name": "Pricing Rule",
+ "description": _("Rules for applying pricing and discount.")
+ },
{
"type": "doctype",
"name": "Product Bundle",
@@ -80,11 +85,6 @@ def get_data():
"type": "doctype",
"name": "Promotional Scheme",
"description": _("Rules for applying different promotional schemes.")
- },
- {
- "type": "doctype",
- "name": "Pricing Rule",
- "description": _("Rules for applying pricing and discount.")
}
]
},
@@ -149,13 +149,6 @@ def get_data():
"reference_doctype": "Purchase Order",
"onboard": 1
},
- {
- "type": "report",
- "is_query_report": True,
- "name": "Supplier-Wise Sales Analytics",
- "reference_doctype": "Stock Ledger Entry",
- "onboard": 1
- },
{
"type": "report",
"is_query_report": True,
@@ -177,6 +170,16 @@ def get_data():
"reference_doctype": "Material Request",
"onboard": 1,
},
+ {
+ "type": "report",
+ "is_query_report": True,
+ "name": "Address And Contacts",
+ "label": _("Supplier Addresses And Contacts"),
+ "reference_doctype": "Address",
+ "route_options": {
+ "party_type": "Supplier"
+ }
+ }
]
},
{
@@ -226,18 +229,15 @@ def get_data():
{
"type": "report",
"is_query_report": True,
- "name": "Material Requests for which Supplier Quotations are not created",
- "reference_doctype": "Material Request"
+ "name": "Supplier-Wise Sales Analytics",
+ "reference_doctype": "Stock Ledger Entry",
+ "onboard": 1
},
{
"type": "report",
"is_query_report": True,
- "name": "Address And Contacts",
- "label": _("Supplier Addresses And Contacts"),
- "reference_doctype": "Address",
- "route_options": {
- "party_type": "Supplier"
- }
+ "name": "Material Requests for which Supplier Quotations are not created",
+ "reference_doctype": "Material Request"
}
]
},
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 001da5b5ea8..5abe7366d0f 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -1200,6 +1200,8 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
child_item = set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docname, d.get("item_code"))
else:
child_item = frappe.get_doc(parent_doctype + ' Item', d.get("docname"))
+ if flt(child_item.get("rate")) == flt(d.get("rate")) and flt(child_item.get("qty")) == flt(d.get("qty")):
+ continue
if parent_doctype == "Sales Order" and flt(d.get("qty")) < flt(child_item.delivered_qty):
frappe.throw(_("Cannot set quantity less than delivered quantity"))
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index 75b896bb134..a47507eaf7b 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -44,6 +44,7 @@ class BuyingController(StockController):
self.validate_stock_or_nonstock_items()
self.validate_warehouse()
self.set_supplier_address()
+ self.validate_asset_return()
if self.doctype=="Purchase Invoice":
self.validate_purchase_receipt_if_update_stock()
@@ -99,6 +100,19 @@ class BuyingController(StockController):
for d in tax_for_valuation:
d.category = 'Total'
msgprint(_('Tax Category has been changed to "Total" because all the Items are non-stock items'))
+
+ def validate_asset_return(self):
+ if self.doctype not in ['Purchase Receipt', 'Purchase Invoice'] or not self.is_return:
+ return
+
+ purchase_doc_field = 'purchase_receipt' if self.doctype == 'Purchase Receipt' else 'purchase_invoice'
+ not_cancelled_asset = [d.name for d in frappe.db.get_all("Asset", {
+ purchase_doc_field: self.return_against,
+ "docstatus": 1
+ })]
+ if self.is_return and len(not_cancelled_asset):
+ frappe.throw(_("{} has submitted assets linked to it. You need to cancel the assets to create purchase return.".format(self.return_against)),
+ title=_("Not Allowed"))
def get_asset_items(self):
if self.doctype not in ['Purchase Order', 'Purchase Invoice', 'Purchase Receipt']:
diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py
index 8b275a64fb3..4d0520abc81 100644
--- a/erpnext/controllers/status_updater.py
+++ b/erpnext/controllers/status_updater.py
@@ -44,17 +44,6 @@ status_map = {
["Closed", "eval:self.status=='Closed'"],
["On Hold", "eval:self.status=='On Hold'"],
],
- "Purchase Invoice": [
- ["Draft", None],
- ["Submitted", "eval:self.docstatus==1"],
- ["Paid", "eval:self.outstanding_amount==0 and self.docstatus==1"],
- ["Return", "eval:self.is_return==1 and self.docstatus==1"],
- ["Debit Note Issued",
- "eval:self.outstanding_amount <= 0 and self.docstatus==1 and self.is_return==0 and get_value('Purchase Invoice', {'is_return': 1, 'return_against': self.name, 'docstatus': 1})"],
- ["Unpaid", "eval:self.outstanding_amount > 0 and getdate(self.due_date) >= getdate(nowdate()) and self.docstatus==1"],
- ["Overdue", "eval:self.outstanding_amount > 0 and getdate(self.due_date) < getdate(nowdate()) and self.docstatus==1"],
- ["Cancelled", "eval:self.docstatus==2"],
- ],
"Purchase Order": [
["Draft", None],
["To Receive and Bill", "eval:self.per_received < 100 and self.per_billed < 100 and self.docstatus == 1"],
@@ -80,6 +69,17 @@ status_map = {
["Cancelled", "eval:self.docstatus==2"],
["Closed", "eval:self.status=='Closed'"],
],
+ "Purchase Invoice": [
+ ["Draft", None],
+ ["Submitted", "eval:self.docstatus==1"],
+ ["Paid", "eval:self.outstanding_amount==0 and self.docstatus==1"],
+ ["Return", "eval:self.is_return==1 and self.docstatus==1"],
+ ["Debit Note Issued",
+ "eval:self.outstanding_amount <= 0 and self.docstatus==1 and self.is_return==0 and get_value('Purchase Invoice', {'is_return': 1, 'return_against': self.name, 'docstatus': 1})"],
+ ["Unpaid", "eval:self.outstanding_amount > 0 and getdate(self.due_date) >= getdate(nowdate()) and self.docstatus==1"],
+ ["Overdue", "eval:self.outstanding_amount > 0 and getdate(self.due_date) < getdate(nowdate()) and self.docstatus==1"],
+ ["Cancelled", "eval:self.docstatus==2"],
+ ],
"Material Request": [
["Draft", None],
["Stopped", "eval:self.status == 'Stopped'"],
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index 2b47a2c09b8..c6d0c7c0a6e 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -34,7 +34,7 @@ class StockController(AccountsController):
gl_entries = self.get_gl_entries(warehouse_account)
make_gl_entries(gl_entries, from_repost=from_repost)
- if repost_future_gle:
+ if (repost_future_gle or self.flags.repost_future_gle):
items, warehouses = self.get_items_and_warehouses()
update_gl_entries_after(self.posting_date, self.posting_time, warehouses, items,
warehouse_account, company=self.company)
@@ -239,6 +239,10 @@ class StockController(AccountsController):
for d in self.items:
if not d.batch_no: continue
+ serial_nos = [sr.name for sr in frappe.get_all("Serial No", {'batch_no': d.batch_no})]
+ if serial_nos:
+ frappe.db.set_value("Serial No", { 'name': ['in', serial_nos] }, "batch_no", None)
+
d.batch_no = None
d.db_set("batch_no", None)
@@ -420,7 +424,7 @@ def get_future_stock_vouchers(posting_date, posting_time, for_warehouses=None, f
for d in frappe.db.sql("""select distinct sle.voucher_type, sle.voucher_no
from `tabStock Ledger Entry` sle
where timestamp(sle.posting_date, sle.posting_time) >= timestamp(%s, %s) {condition}
- order by timestamp(sle.posting_date, sle.posting_time) asc, creation asc""".format(condition=condition),
+ order by timestamp(sle.posting_date, sle.posting_time) asc, creation asc for update""".format(condition=condition),
tuple([posting_date, posting_time] + values), as_dict=True):
future_stock_vouchers.append([d.voucher_type, d.voucher_no])
diff --git a/erpnext/demo/user/fixed_asset.py b/erpnext/demo/user/fixed_asset.py
index e6d16872024..dc094e1c918 100644
--- a/erpnext/demo/user/fixed_asset.py
+++ b/erpnext/demo/user/fixed_asset.py
@@ -6,46 +6,28 @@ from __future__ import unicode_literals
import frappe
from frappe.utils.make_random import get_random
-from erpnext.assets.doctype.asset.asset import make_purchase_invoice, make_sales_invoice
+from erpnext.assets.doctype.asset.asset import make_sales_invoice
from erpnext.assets.doctype.asset.depreciation import post_depreciation_entries, scrap_asset
+
def work():
frappe.set_user(frappe.db.get_global('demo_accounts_user'))
- asset_list = make_asset_purchase_entry()
-
- if not asset_list:
- # fixed_asset.work() already run
- return
-
# Enable booking asset depreciation entry automatically
frappe.db.set_value("Accounts Settings", None, "book_asset_depreciation_entry_automatically", 1)
-
+
# post depreciation entries as on today
post_depreciation_entries()
-
+
# scrap a random asset
frappe.db.set_value("Company", "Wind Power LLC", "disposal_account", "Gain/Loss on Asset Disposal - WPL")
-
+
asset = get_random_asset()
scrap_asset(asset.name)
-
- # Sell a random asset
- sell_an_asset()
-def make_asset_purchase_entry():
- asset_list = frappe.get_all("Asset", filters={"purchase_invoice": ["in", ("", None)]},
- fields=["name", "item_code", "gross_purchase_amount", "company", "purchase_date"])
-
- # make purchase invoice
- for asset in asset_list:
- pi = make_purchase_invoice(asset.name, asset.item_code, asset.gross_purchase_amount,
- asset.company, asset.purchase_date)
- pi.supplier = get_random("Supplier")
- pi.save()
- pi.submit()
-
- return asset_list
+ # Sell a random asset
+ sell_an_asset()
+
def sell_an_asset():
asset = get_random_asset()
@@ -55,8 +37,9 @@ def sell_an_asset():
if asset.value_after_depreciation else asset.gross_purchase_amount * 0.9
si.save()
si.submit()
-
+
+
def get_random_asset():
return frappe.db.sql(""" select name, item_code, value_after_depreciation, gross_purchase_amount
- from `tabAsset`
+ from `tabAsset`
where docstatus=1 and status not in ("Scrapped", "Sold") order by rand() limit 1""", as_dict=1)[0]
diff --git a/erpnext/erpnext_integrations/connectors/woocommerce_connection.py b/erpnext/erpnext_integrations/connectors/woocommerce_connection.py
index 28c2ab9e545..4422d23e380 100644
--- a/erpnext/erpnext_integrations/connectors/woocommerce_connection.py
+++ b/erpnext/erpnext_integrations/connectors/woocommerce_connection.py
@@ -47,11 +47,12 @@ def _order(*args, **kwargs):
return "success"
if event == "created":
+ sys_lang = frappe.get_single("System Settings").language or 'en'
raw_billing_data = order.get("billing")
customer_name = raw_billing_data.get("first_name") + " " + raw_billing_data.get("last_name")
link_customer_and_address(raw_billing_data, customer_name)
- link_items(order.get("line_items"), woocommerce_settings)
- create_sales_order(order, woocommerce_settings, customer_name)
+ link_items(order.get("line_items"), woocommerce_settings, sys_lang)
+ create_sales_order(order, woocommerce_settings, customer_name, sys_lang)
def link_customer_and_address(raw_billing_data, customer_name):
customer_woo_com_email = raw_billing_data.get("email")
@@ -100,7 +101,7 @@ def link_customer_and_address(raw_billing_data, customer_name):
frappe.rename_doc("Address", old_address_title, new_address_title)
-def link_items(items_list, woocommerce_settings):
+def link_items(items_list, woocommerce_settings, sys_lang):
for item_data in items_list:
item_woo_com_id = item_data.get("product_id")
@@ -112,14 +113,14 @@ def link_items(items_list, woocommerce_settings):
item = frappe.new_doc("Item")
item.item_name = item_data.get("name")
- item.item_code = _("woocommerce - {0}").format(item_data.get("product_id"))
+ item.item_code = _("woocommerce - {0}", sys_lang).format(item_data.get("product_id"))
item.woocommerce_id = item_data.get("product_id")
- item.item_group = _("WooCommerce Products")
- item.stock_uom = woocommerce_settings.uom or _("Nos")
+ item.item_group = _("WooCommerce Products", sys_lang)
+ item.stock_uom = woocommerce_settings.uom or _("Nos", sys_lang)
item.flags.ignore_mandatory = True
item.save()
-def create_sales_order(order, woocommerce_settings, customer_name):
+def create_sales_order(order, woocommerce_settings, customer_name, sys_lang):
new_sales_order = frappe.new_doc("Sales Order")
new_sales_order.customer = customer_name
@@ -133,14 +134,14 @@ def create_sales_order(order, woocommerce_settings, customer_name):
new_sales_order.company = woocommerce_settings.company
- set_items_in_sales_order(new_sales_order, woocommerce_settings, order)
+ set_items_in_sales_order(new_sales_order, woocommerce_settings, order, sys_lang)
new_sales_order.flags.ignore_mandatory = True
new_sales_order.insert()
new_sales_order.submit()
frappe.db.commit()
-def set_items_in_sales_order(new_sales_order, woocommerce_settings, order):
+def set_items_in_sales_order(new_sales_order, woocommerce_settings, order, sys_lang):
company_abbr = frappe.db.get_value('Company', woocommerce_settings.company, 'abbr')
for item in order.get("line_items"):
@@ -154,10 +155,10 @@ def set_items_in_sales_order(new_sales_order, woocommerce_settings, order):
"item_name": found_item.item_name,
"description": found_item.item_name,
"delivery_date": new_sales_order.delivery_date,
- "uom": woocommerce_settings.uom or _("Nos"),
+ "uom": woocommerce_settings.uom or _("Nos", sys_lang),
"qty": item.get("quantity"),
"rate": item.get("price"),
- "warehouse": woocommerce_settings.warehouse or _("Stores - {0}").format(company_abbr)
+ "warehouse": woocommerce_settings.warehouse or _("Stores - {0}", sys_lang).format(company_abbr)
})
add_tax_details(new_sales_order, ordered_items_tax, "Ordered Item tax", woocommerce_settings.tax_account)
diff --git a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py
index 2f39dc596bf..3bc8db5e78a 100644
--- a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py
+++ b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py
@@ -165,6 +165,9 @@ def create_item_code(amazon_item_json, sku):
return item.name
def create_manufacturer(amazon_item_json):
+ if not amazon_item_json.Product.AttributeSets.ItemAttributes.Manufacturer:
+ return None
+
existing_manufacturer = frappe.db.get_value("Manufacturer",
filters={"short_name":amazon_item_json.Product.AttributeSets.ItemAttributes.Manufacturer})
@@ -177,6 +180,9 @@ def create_manufacturer(amazon_item_json):
return existing_manufacturer
def create_brand(amazon_item_json):
+ if not amazon_item_json.Product.AttributeSets.ItemAttributes.Brand:
+ return None
+
existing_brand = frappe.db.get_value("Brand",
filters={"brand":amazon_item_json.Product.AttributeSets.ItemAttributes.Brand})
if not existing_brand:
diff --git a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.py b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.py
index 249a73f9fbb..c222afbb6c1 100644
--- a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.py
+++ b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.py
@@ -7,7 +7,6 @@ import frappe
from frappe.model.document import Document
import dateutil
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
-from erpnext.erpnext_integrations.doctype.amazon_mws_settings.amazon_methods import get_products_details, get_orders
class AmazonMWSSettings(Document):
def validate(self):
@@ -19,12 +18,12 @@ class AmazonMWSSettings(Document):
def get_products_details(self):
if self.enable_amazon == 1:
- get_products_details()
+ frappe.enqueue('erpnext.erpnext_integrations.doctype.amazon_mws_settings.amazon_methods.get_products_details')
def get_order_details(self):
if self.enable_amazon == 1:
after_date = dateutil.parser.parse(self.after_date).strftime("%Y-%m-%d")
- get_orders(after_date = after_date)
+ frappe.enqueue('erpnext.erpnext_integrations.doctype.amazon_mws_settings.amazon_methods.get_orders', after_date=after_date)
def schedule_get_order_details():
mws_settings = frappe.get_doc("Amazon MWS Settings")
diff --git a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/xml_utils.py b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/xml_utils.py
index 58db669411a..a25a29f9e5f 100644
--- a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/xml_utils.py
+++ b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/xml_utils.py
@@ -33,7 +33,10 @@ class object_dict(dict):
def __getattr__(self, item):
- d = self.__getitem__(item)
+ try:
+ d = self.__getitem__(item)
+ except KeyError:
+ return None
if isinstance(d, dict) and 'value' in d and len(d) == 1:
return d['value']
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
index 7aa41c546c0..12248fcdce3 100755
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
@@ -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='{0}' and pp.parent=ct.name and pp.appointment_booked=0
- order by ct.creation desc""".format(patient))
+ where ct.patient=%(patient)s and pp.parent=ct.name and pp.appointment_booked=0
+ order by ct.creation desc""", {"patient": patient})
diff --git a/erpnext/hr/doctype/additional_salary/additional_salary.js b/erpnext/hr/doctype/additional_salary/additional_salary.js
index d0f64ab51bb..18f6b8b52d5 100644
--- a/erpnext/hr/doctype/additional_salary/additional_salary.js
+++ b/erpnext/hr/doctype/additional_salary/additional_salary.js
@@ -8,7 +8,8 @@ frappe.ui.form.on('Additional Salary', {
frm.set_query("employee", function() {
return {
filters: {
- company: frm.doc.company
+ company: frm.doc.company,
+ status: "Active"
}
};
});
diff --git a/erpnext/hr/doctype/additional_salary/additional_salary.py b/erpnext/hr/doctype/additional_salary/additional_salary.py
index 8498b3d277d..bc7dcee55e4 100644
--- a/erpnext/hr/doctype/additional_salary/additional_salary.py
+++ b/erpnext/hr/doctype/additional_salary/additional_salary.py
@@ -39,19 +39,21 @@ class AdditionalSalary(Document):
return amount_per_day * no_of_days
@frappe.whitelist()
-def get_additional_salary_component(employee, start_date, end_date):
+def get_additional_salary_component(employee, start_date, end_date, component_type):
additional_components = frappe.db.sql("""
select salary_component, sum(amount) as amount, overwrite_salary_structure_amount, deduct_full_tax_on_selected_payroll_date
from `tabAdditional Salary`
where employee=%(employee)s
and docstatus = 1
and payroll_date between %(from_date)s and %(to_date)s
+ and type = %(component_type)s
group by salary_component, overwrite_salary_structure_amount
order by salary_component, overwrite_salary_structure_amount
""", {
'employee': employee,
'from_date': start_date,
- 'to_date': end_date
+ 'to_date': end_date,
+ 'component_type': "Earning" if component_type == "earnings" else "Deduction"
}, as_dict=1)
additional_components_list = []
diff --git a/erpnext/hr/doctype/attendance/attendance.json b/erpnext/hr/doctype/attendance/attendance.json
index bc89b368d30..20974a0b7d2 100644
--- a/erpnext/hr/doctype/attendance/attendance.json
+++ b/erpnext/hr/doctype/attendance/attendance.json
@@ -57,11 +57,12 @@
{
"fetch_from": "employee.employee_name",
"fieldname": "employee_name",
- "fieldtype": "Read Only",
+ "fieldtype": "Data",
"in_global_search": 1,
"label": "Employee Name",
"oldfieldname": "employee_name",
- "oldfieldtype": "Data"
+ "oldfieldtype": "Data",
+ "read_only": 1
},
{
"default": "Present",
@@ -173,7 +174,7 @@
"icon": "fa fa-ok",
"idx": 1,
"is_submittable": 1,
- "modified": "2019-07-29 20:35:40.845422",
+ "modified": "2020-02-19 14:25:32.945842",
"modified_by": "Administrator",
"module": "HR",
"name": "Attendance",
diff --git a/erpnext/hr/doctype/department/department.py b/erpnext/hr/doctype/department/department.py
index 9b2b5817660..2cef5092767 100644
--- a/erpnext/hr/doctype/department/department.py
+++ b/erpnext/hr/doctype/department/department.py
@@ -48,12 +48,17 @@ 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='{0}'".format(get_root_of("Department"))
+ condition = "name=%(name)s"
elif company:
- condition = "parent_department='{0}' and company='{1}'".format(parent, company)
+ condition = "parent_department=%(parent)s and company=%(company)s"
else:
- condition = "parent_department = '{0}'".format(parent)
+ condition = "parent_department = %(parent)s"
return frappe.db.sql("""
select
@@ -62,7 +67,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), as_dict=1)
+ order by name""".format(doctype=doctype, condition=condition), var_dict, as_dict=1)
@frappe.whitelist()
def add_node():
diff --git a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.py b/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.py
index fea4246d646..feaa92590a3 100644
--- a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.py
+++ b/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.py
@@ -190,6 +190,7 @@ def get_benefit_component_amount(employee, start_date, end_date, salary_componen
component_max_benefit, depends_on_payment_days = frappe.db.get_value("Salary Component",
salary_component, ["max_benefit_amount", "depends_on_payment_days"])
+ benefit_amount = 0
if benefit_application:
benefit_amount = frappe.db.get_value("Employee Benefit Application Detail",
{"parent": benefit_application[0][0], "earning_component": salary_component}, "amount")
diff --git a/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json b/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json
index 9bf69daf65a..1b1889b205f 100644
--- a/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json
+++ b/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json
@@ -70,7 +70,7 @@
"label": "Amount",
"oldfieldname": "tax_amount",
"oldfieldtype": "Currency",
- "options": "currency"
+ "options": "Company:company:default_currency"
},
{
"columns": 2,
@@ -80,7 +80,7 @@
"label": "Total",
"oldfieldname": "total",
"oldfieldtype": "Currency",
- "options": "currency",
+ "options": "Company:company:default_currency",
"read_only": 1
},
{
diff --git a/erpnext/hr/doctype/leave_application/leave_application.json b/erpnext/hr/doctype/leave_application/leave_application.json
index cdb1add3918..460be514b59 100644
--- a/erpnext/hr/doctype/leave_application/leave_application.json
+++ b/erpnext/hr/doctype/leave_application/leave_application.json
@@ -1,332 +1,336 @@
{
- "allow_import": 1,
- "autoname": "naming_series:",
- "creation": "2013-02-20 11:18:11",
- "description": "Apply / Approve Leaves",
- "doctype": "DocType",
- "document_type": "Document",
- "engine": "InnoDB",
- "field_order": [
- "naming_series",
- "employee",
- "employee_name",
- "column_break_4",
- "leave_type",
- "department",
- "leave_balance",
- "section_break_5",
- "from_date",
- "to_date",
- "half_day",
- "half_day_date",
- "total_leave_days",
- "column_break1",
- "description",
- "section_break_7",
- "leave_approver",
- "leave_approver_name",
- "column_break_18",
- "status",
- "salary_slip",
- "sb10",
- "posting_date",
- "follow_via_email",
- "color",
- "column_break_17",
- "company",
- "letter_head",
- "amended_from"
- ],
- "fields": [
- {
- "fieldname": "naming_series",
- "fieldtype": "Select",
- "label": "Series",
- "no_copy": 1,
- "options": "HR-LAP-.YYYY.-",
- "print_hide": 1,
- "reqd": 1,
- "set_only_once": 1
- },
- {
- "fieldname": "employee",
- "fieldtype": "Link",
- "in_global_search": 1,
- "in_standard_filter": 1,
- "label": "Employee",
- "options": "Employee",
- "reqd": 1,
- "search_index": 1
- },
- {
- "fieldname": "employee_name",
- "fieldtype": "Data",
- "in_global_search": 1,
- "label": "Employee Name",
- "read_only": 1
- },
- {
- "fieldname": "column_break_4",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "leave_type",
- "fieldtype": "Link",
- "ignore_user_permissions": 1,
- "in_standard_filter": 1,
- "label": "Leave Type",
- "options": "Leave Type",
- "reqd": 1,
- "search_index": 1
- },
- {
- "fetch_from": "employee.department",
- "fieldname": "department",
- "fieldtype": "Link",
- "label": "Department",
- "options": "Department",
- "read_only": 1
- },
- {
- "fieldname": "leave_balance",
- "fieldtype": "Float",
- "label": "Leave Balance Before Application",
- "no_copy": 1,
- "read_only": 1
- },
- {
- "fieldname": "section_break_5",
- "fieldtype": "Section Break"
- },
- {
- "fieldname": "from_date",
- "fieldtype": "Date",
- "in_list_view": 1,
- "label": "From Date",
- "reqd": 1,
- "search_index": 1
- },
- {
- "fieldname": "to_date",
- "fieldtype": "Date",
- "label": "To Date",
- "reqd": 1,
- "search_index": 1
- },
- {
- "default": "0",
- "fieldname": "half_day",
- "fieldtype": "Check",
- "label": "Half Day"
- },
- {
- "depends_on": "eval:doc.half_day && (doc.from_date != doc.to_date)",
- "fieldname": "half_day_date",
- "fieldtype": "Date",
- "label": "Half Day Date"
- },
- {
- "fieldname": "total_leave_days",
- "fieldtype": "Float",
- "in_list_view": 1,
- "label": "Total Leave Days",
- "no_copy": 1,
- "precision": "1",
- "read_only": 1
- },
- {
- "fieldname": "column_break1",
- "fieldtype": "Column Break",
- "print_width": "50%",
- "width": "50%"
- },
- {
- "fieldname": "description",
- "fieldtype": "Small Text",
- "label": "Reason"
- },
- {
- "fieldname": "section_break_7",
- "fieldtype": "Section Break"
- },
- {
- "fieldname": "leave_approver",
- "fieldtype": "Link",
- "label": "Leave Approver",
- "options": "User"
- },
- {
- "fieldname": "leave_approver_name",
- "fieldtype": "Data",
- "label": "Leave Approver Name",
- "read_only": 1
- },
- {
- "fieldname": "column_break_18",
- "fieldtype": "Column Break"
- },
- {
- "default": "Open",
- "fieldname": "status",
- "fieldtype": "Select",
- "in_standard_filter": 1,
- "label": "Status",
- "no_copy": 1,
- "options": "Open\nApproved\nRejected\nCancelled"
- },
- {
- "fieldname": "sb10",
- "fieldtype": "Section Break"
- },
- {
- "default": "Today",
- "fieldname": "posting_date",
- "fieldtype": "Date",
- "label": "Posting Date",
- "no_copy": 1,
- "reqd": 1
- },
- {
- "fieldname": "company",
- "fieldtype": "Link",
- "label": "Company",
- "options": "Company",
- "remember_last_selected_value": 1,
- "reqd": 1
- },
- {
- "allow_on_submit": 1,
- "default": "1",
- "fieldname": "follow_via_email",
- "fieldtype": "Check",
- "label": "Follow via Email",
- "print_hide": 1
- },
- {
- "fieldname": "column_break_17",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "salary_slip",
- "fieldtype": "Link",
- "label": "Salary Slip",
- "options": "Salary Slip",
- "print_hide": 1
- },
- {
- "allow_on_submit": 1,
- "fieldname": "letter_head",
- "fieldtype": "Link",
- "ignore_user_permissions": 1,
- "label": "Letter Head",
- "options": "Letter Head",
- "print_hide": 1
- },
- {
- "allow_on_submit": 1,
- "fieldname": "color",
- "fieldtype": "Color",
- "label": "Color",
- "print_hide": 1
- },
- {
- "fieldname": "amended_from",
- "fieldtype": "Link",
- "ignore_user_permissions": 1,
- "label": "Amended From",
- "no_copy": 1,
- "options": "Leave Application",
- "print_hide": 1,
- "read_only": 1
- }
- ],
- "icon": "fa fa-calendar",
- "idx": 1,
- "is_submittable": 1,
- "max_attachments": 3,
- "modified": "2019-08-13 13:32:04.860848",
- "modified_by": "Administrator",
- "module": "HR",
- "name": "Leave Application",
- "owner": "Administrator",
- "permissions": [
- {
- "create": 1,
- "email": 1,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Employee",
- "share": 1,
- "write": 1
- },
- {
- "amend": 1,
- "cancel": 1,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "HR Manager",
- "set_user_permissions": 1,
- "share": 1,
- "submit": 1,
- "write": 1
- },
- {
- "permlevel": 1,
- "read": 1,
- "role": "All"
- },
- {
- "amend": 1,
- "cancel": 1,
- "create": 1,
- "delete": 1,
- "email": 1,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "HR User",
- "set_user_permissions": 1,
- "share": 1,
- "submit": 1,
- "write": 1
- },
- {
- "amend": 1,
- "cancel": 1,
- "delete": 1,
- "email": 1,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Leave Approver",
- "share": 1,
- "submit": 1,
- "write": 1
- },
- {
- "permlevel": 1,
- "read": 1,
- "report": 1,
- "role": "HR User",
- "write": 1
- },
- {
- "permlevel": 1,
- "read": 1,
- "report": 1,
- "role": "Leave Approver",
- "write": 1
- }
- ],
- "search_fields": "employee,employee_name,leave_type,from_date,to_date,total_leave_days",
- "sort_field": "modified",
- "sort_order": "DESC",
- "timeline_field": "employee",
- "title_field": "employee_name"
- }
\ No newline at end of file
+ "actions": [],
+ "allow_import": 1,
+ "autoname": "naming_series:",
+ "creation": "2013-02-20 11:18:11",
+ "description": "Apply / Approve Leaves",
+ "doctype": "DocType",
+ "document_type": "Document",
+ "engine": "InnoDB",
+ "field_order": [
+ "naming_series",
+ "employee",
+ "employee_name",
+ "column_break_4",
+ "leave_type",
+ "department",
+ "leave_balance",
+ "section_break_5",
+ "from_date",
+ "to_date",
+ "half_day",
+ "half_day_date",
+ "total_leave_days",
+ "column_break1",
+ "description",
+ "section_break_7",
+ "leave_approver",
+ "leave_approver_name",
+ "column_break_18",
+ "status",
+ "salary_slip",
+ "sb10",
+ "posting_date",
+ "follow_via_email",
+ "color",
+ "column_break_17",
+ "company",
+ "letter_head",
+ "amended_from"
+ ],
+ "fields": [
+ {
+ "fieldname": "naming_series",
+ "fieldtype": "Select",
+ "label": "Series",
+ "no_copy": 1,
+ "options": "HR-LAP-.YYYY.-",
+ "print_hide": 1,
+ "reqd": 1,
+ "set_only_once": 1
+ },
+ {
+ "fieldname": "employee",
+ "fieldtype": "Link",
+ "in_global_search": 1,
+ "in_standard_filter": 1,
+ "label": "Employee",
+ "options": "Employee",
+ "reqd": 1,
+ "search_index": 1
+ },
+ {
+ "fieldname": "employee_name",
+ "fieldtype": "Data",
+ "in_global_search": 1,
+ "label": "Employee Name",
+ "read_only": 1
+ },
+ {
+ "fieldname": "column_break_4",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "leave_type",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "in_standard_filter": 1,
+ "label": "Leave Type",
+ "options": "Leave Type",
+ "reqd": 1,
+ "search_index": 1
+ },
+ {
+ "fetch_from": "employee.department",
+ "fieldname": "department",
+ "fieldtype": "Link",
+ "label": "Department",
+ "options": "Department",
+ "read_only": 1
+ },
+ {
+ "fieldname": "leave_balance",
+ "fieldtype": "Float",
+ "label": "Leave Balance Before Application",
+ "no_copy": 1,
+ "read_only": 1
+ },
+ {
+ "fieldname": "section_break_5",
+ "fieldtype": "Section Break"
+ },
+ {
+ "fieldname": "from_date",
+ "fieldtype": "Date",
+ "in_list_view": 1,
+ "label": "From Date",
+ "reqd": 1,
+ "search_index": 1
+ },
+ {
+ "fieldname": "to_date",
+ "fieldtype": "Date",
+ "label": "To Date",
+ "reqd": 1,
+ "search_index": 1
+ },
+ {
+ "default": "0",
+ "fieldname": "half_day",
+ "fieldtype": "Check",
+ "label": "Half Day"
+ },
+ {
+ "depends_on": "eval:doc.half_day && (doc.from_date != doc.to_date)",
+ "fieldname": "half_day_date",
+ "fieldtype": "Date",
+ "label": "Half Day Date"
+ },
+ {
+ "fieldname": "total_leave_days",
+ "fieldtype": "Float",
+ "in_list_view": 1,
+ "label": "Total Leave Days",
+ "no_copy": 1,
+ "precision": "1",
+ "read_only": 1
+ },
+ {
+ "fieldname": "column_break1",
+ "fieldtype": "Column Break",
+ "print_width": "50%",
+ "width": "50%"
+ },
+ {
+ "fieldname": "description",
+ "fieldtype": "Small Text",
+ "label": "Reason"
+ },
+ {
+ "fieldname": "section_break_7",
+ "fieldtype": "Section Break"
+ },
+ {
+ "fieldname": "leave_approver",
+ "fieldtype": "Link",
+ "label": "Leave Approver",
+ "options": "User"
+ },
+ {
+ "fieldname": "leave_approver_name",
+ "fieldtype": "Data",
+ "label": "Leave Approver Name",
+ "read_only": 1
+ },
+ {
+ "fieldname": "column_break_18",
+ "fieldtype": "Column Break"
+ },
+ {
+ "default": "Open",
+ "fieldname": "status",
+ "fieldtype": "Select",
+ "in_standard_filter": 1,
+ "label": "Status",
+ "no_copy": 1,
+ "options": "Open\nApproved\nRejected\nCancelled",
+ "permlevel": 1
+ },
+ {
+ "fieldname": "sb10",
+ "fieldtype": "Section Break"
+ },
+ {
+ "default": "Today",
+ "fieldname": "posting_date",
+ "fieldtype": "Date",
+ "label": "Posting Date",
+ "no_copy": 1,
+ "reqd": 1
+ },
+ {
+ "fieldname": "company",
+ "fieldtype": "Link",
+ "label": "Company",
+ "options": "Company",
+ "read_only": 1,
+ "remember_last_selected_value": 1,
+ "reqd": 1
+ },
+ {
+ "allow_on_submit": 1,
+ "default": "1",
+ "fieldname": "follow_via_email",
+ "fieldtype": "Check",
+ "label": "Follow via Email",
+ "print_hide": 1
+ },
+ {
+ "fieldname": "column_break_17",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "salary_slip",
+ "fieldtype": "Link",
+ "label": "Salary Slip",
+ "options": "Salary Slip",
+ "print_hide": 1
+ },
+ {
+ "allow_on_submit": 1,
+ "fieldname": "letter_head",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "label": "Letter Head",
+ "options": "Letter Head",
+ "print_hide": 1
+ },
+ {
+ "allow_on_submit": 1,
+ "fieldname": "color",
+ "fieldtype": "Color",
+ "label": "Color",
+ "print_hide": 1
+ },
+ {
+ "fieldname": "amended_from",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "label": "Amended From",
+ "no_copy": 1,
+ "options": "Leave Application",
+ "print_hide": 1,
+ "read_only": 1
+ }
+ ],
+ "icon": "fa fa-calendar",
+ "idx": 1,
+ "is_submittable": 1,
+ "links": [],
+ "max_attachments": 3,
+ "modified": "2020-03-10 22:40:43.487721",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Leave Application",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "create": 1,
+ "email": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Employee",
+ "share": 1,
+ "write": 1
+ },
+ {
+ "amend": 1,
+ "cancel": 1,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "HR Manager",
+ "set_user_permissions": 1,
+ "share": 1,
+ "submit": 1,
+ "write": 1
+ },
+ {
+ "permlevel": 1,
+ "read": 1,
+ "role": "All"
+ },
+ {
+ "amend": 1,
+ "cancel": 1,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "HR User",
+ "set_user_permissions": 1,
+ "share": 1,
+ "submit": 1,
+ "write": 1
+ },
+ {
+ "amend": 1,
+ "cancel": 1,
+ "delete": 1,
+ "email": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Leave Approver",
+ "share": 1,
+ "submit": 1,
+ "write": 1
+ },
+ {
+ "permlevel": 1,
+ "read": 1,
+ "report": 1,
+ "role": "HR User",
+ "write": 1
+ },
+ {
+ "permlevel": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Leave Approver",
+ "write": 1
+ }
+ ],
+ "search_fields": "employee,employee_name,leave_type,from_date,to_date,total_leave_days",
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "timeline_field": "employee",
+ "title_field": "employee_name"
+}
diff --git a/erpnext/hr/doctype/leave_application/leave_application.py b/erpnext/hr/doctype/leave_application/leave_application.py
index 8c109464fdf..39e5e1132ca 100755
--- a/erpnext/hr/doctype/leave_application/leave_application.py
+++ b/erpnext/hr/doctype/leave_application/leave_application.py
@@ -366,7 +366,8 @@ class LeaveApplication(Document):
leaves=self.total_leave_days * -1,
from_date=self.from_date,
to_date=self.to_date,
- is_lwp=lwp
+ is_lwp=lwp,
+ holiday_list=get_holiday_list_for_employee(self.employee)
)
create_leave_ledger_entry(self, args, submit)
@@ -376,7 +377,9 @@ class LeaveApplication(Document):
from_date=self.from_date,
to_date=expiry_date,
leaves=(date_diff(expiry_date, self.from_date) + 1) * -1,
- is_lwp=lwp
+ is_lwp=lwp,
+ holiday_list=get_holiday_list_for_employee(self.employee),
+
)
create_leave_ledger_entry(self, args, submit)
@@ -402,7 +405,7 @@ def get_allocation_expiry(employee, leave_type, to_date, from_date):
return expiry[0]['to_date'] if expiry else None
@frappe.whitelist()
-def get_number_of_leave_days(employee, leave_type, from_date, to_date, half_day = None, half_day_date = None):
+def get_number_of_leave_days(employee, leave_type, from_date, to_date, half_day = None, half_day_date = None, holiday_list = None):
number_of_days = 0
if cint(half_day) == 1:
if from_date == to_date:
@@ -416,7 +419,7 @@ def get_number_of_leave_days(employee, leave_type, from_date, to_date, half_day
number_of_days = date_diff(to_date, from_date) + 1
if not frappe.db.get_value("Leave Type", leave_type, "include_holiday"):
- number_of_days = flt(number_of_days) - flt(get_holidays(employee, from_date, to_date))
+ number_of_days = flt(number_of_days) - flt(get_holidays(employee, from_date, to_date, holiday_list=holiday_list))
return number_of_days
@frappe.whitelist()
@@ -567,7 +570,7 @@ def get_leaves_for_period(employee, leave_type, from_date, to_date):
{'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, half_day, half_day_date) * -1
+ leave_entry.from_date, leave_entry.to_date, half_day, half_day_date, holiday_list=leave_entry.holiday_list) * -1
return leave_days
@@ -580,7 +583,7 @@ 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_name, transaction_type,
+ employee, leave_type, from_date, to_date, leaves, transaction_name, transaction_type, holiday_list,
is_carry_forward, is_expired
FROM `tabLeave Ledger Entry`
WHERE employee=%(employee)s AND leave_type=%(leave_type)s
@@ -596,9 +599,10 @@ def get_leave_entries(employee, leave_type, from_date, to_date):
}, as_dict=1)
@frappe.whitelist()
-def get_holidays(employee, from_date, to_date):
+def get_holidays(employee, from_date, to_date, holiday_list = None):
'''get holidays between two dates for the given employee'''
- holiday_list = get_holiday_list_for_employee(employee)
+ if not holiday_list:
+ holiday_list = get_holiday_list_for_employee(employee)
holidays = frappe.db.sql("""select count(distinct holiday_date) from `tabHoliday` h1, `tabHoliday List` h2
where h1.parent = h2.name and h1.holiday_date between %s and %s
diff --git a/erpnext/hr/doctype/leave_encashment/leave_encashment.py b/erpnext/hr/doctype/leave_encashment/leave_encashment.py
index 42f0179baf5..ad2cc02fd7c 100644
--- a/erpnext/hr/doctype/leave_encashment/leave_encashment.py
+++ b/erpnext/hr/doctype/leave_encashment/leave_encashment.py
@@ -64,6 +64,9 @@ class LeaveEncashment(Document):
allocation = self.get_leave_allocation()
+ if not allocation:
+ frappe.throw(_("No Leaves Allocated to Employee: {0} for Leave Type: {1}").format(self.employee, self.leave_type))
+
self.leave_balance = allocation.total_leaves_allocated - allocation.carry_forwarded_leaves_count\
- get_unused_leaves(self.employee, self.leave_type, allocation.from_date, self.encashment_date)
@@ -116,4 +119,4 @@ def create_leave_encashment(leave_allocation):
leave_type=allocation.leave_type,
encashment_date=allocation.to_date
))
- leave_encashment.insert(ignore_permissions=True)
\ No newline at end of file
+ leave_encashment.insert(ignore_permissions=True)
diff --git a/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.json b/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.json
index 771e706bbb3..a5ac3f3d471 100644
--- a/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.json
+++ b/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.json
@@ -1,4 +1,5 @@
{
+ "actions": [],
"creation": "2019-05-09 15:47:39.760406",
"doctype": "DocType",
"engine": "InnoDB",
@@ -12,6 +13,7 @@
"column_break_7",
"from_date",
"to_date",
+ "holiday_list",
"is_carry_forward",
"is_expired",
"is_lwp",
@@ -98,11 +100,18 @@
"fieldname": "is_lwp",
"fieldtype": "Check",
"label": "Is Leave Without Pay"
+ },
+ {
+ "fieldname": "holiday_list",
+ "fieldtype": "Link",
+ "label": "Holiday List",
+ "options": "Holiday List"
}
],
"in_create": 1,
"is_submittable": 1,
- "modified": "2019-08-20 14:40:04.130799",
+ "links": [],
+ "modified": "2020-02-27 14:40:10.502605",
"modified_by": "Administrator",
"module": "HR",
"name": "Leave Ledger Entry",
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py
index 0171643b13c..e126db5f5b1 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.py
@@ -298,9 +298,11 @@ class SalarySlip(TransactionBase):
def calculate_net_pay(self):
if self.salary_structure:
- self.calculate_component_amounts()
-
+ self.calculate_component_amounts("earnings")
self.gross_pay = self.get_component_totals("earnings")
+
+ if self.salary_structure:
+ self.calculate_component_amounts("deductions")
self.total_deduction = self.get_component_totals("deductions")
self.set_loan_repayment()
@@ -308,25 +310,27 @@ class SalarySlip(TransactionBase):
self.net_pay = flt(self.gross_pay) - (flt(self.total_deduction) + flt(self.total_loan_repayment))
self.rounded_total = rounded(self.net_pay)
- def calculate_component_amounts(self):
+ def calculate_component_amounts(self, component_type):
if not getattr(self, '_salary_structure_doc', None):
self._salary_structure_doc = frappe.get_doc('Salary Structure', self.salary_structure)
payroll_period = get_payroll_period(self.start_date, self.end_date, self.company)
- self.add_structure_components()
- self.add_employee_benefits(payroll_period)
- self.add_additional_salary_components()
- self.add_tax_components(payroll_period)
- self.set_component_amounts_based_on_payment_days()
+ self.add_structure_components(component_type)
+ self.add_additional_salary_components(component_type)
+ if component_type == "earnings":
+ self.add_employee_benefits(payroll_period)
+ else:
+ self.add_tax_components(payroll_period)
- def add_structure_components(self):
+ self.set_component_amounts_based_on_payment_days(component_type)
+
+ def add_structure_components(self, component_type):
data = self.get_data_for_eval()
- for key in ('earnings', 'deductions'):
- for struct_row in self._salary_structure_doc.get(key):
- amount = self.eval_condition_and_formula(struct_row, data)
- if amount and struct_row.statistical_component == 0:
- self.update_component_row(struct_row, amount, key)
+ for struct_row in self._salary_structure_doc.get(component_type):
+ amount = self.eval_condition_and_formula(struct_row, data)
+ if amount and struct_row.statistical_component == 0:
+ self.update_component_row(struct_row, amount, component_type)
def get_data_for_eval(self):
'''Returns data for evaluating formula'''
@@ -399,14 +403,15 @@ class SalarySlip(TransactionBase):
amount = last_benefit.amount
self.update_component_row(frappe._dict(last_benefit.struct_row), amount, "earnings")
- def add_additional_salary_components(self):
- additional_components = get_additional_salary_component(self.employee, self.start_date, self.end_date)
+ def add_additional_salary_components(self, component_type):
+ additional_components = get_additional_salary_component(self.employee,
+ self.start_date, self.end_date, component_type)
if additional_components:
for additional_component in additional_components:
amount = additional_component.amount
overwrite = additional_component.overwrite
- key = "earnings" if additional_component.type == "Earning" else "deductions"
- self.update_component_row(frappe._dict(additional_component.struct_row), amount, key, overwrite=overwrite)
+ self.update_component_row(frappe._dict(additional_component.struct_row), amount,
+ component_type, overwrite=overwrite)
def add_tax_components(self, payroll_period):
# Calculate variable_based_on_taxable_salary after all components updated in salary slip
@@ -735,7 +740,7 @@ class SalarySlip(TransactionBase):
total += d.amount
return total
- def set_component_amounts_based_on_payment_days(self):
+ def set_component_amounts_based_on_payment_days(self, component_type):
joining_date, relieving_date = frappe.get_cached_value("Employee", self.employee,
["date_of_joining", "relieving_date"])
@@ -745,9 +750,8 @@ class SalarySlip(TransactionBase):
if not joining_date:
frappe.throw(_("Please set the Date Of Joining for employee {0}").format(frappe.bold(self.employee_name)))
- for component_type in ("earnings", "deductions"):
- for d in self.get(component_type):
- d.amount = self.get_amount_based_on_payment_days(d, joining_date, relieving_date)[0]
+ for d in self.get(component_type):
+ d.amount = self.get_amount_based_on_payment_days(d, joining_date, relieving_date)[0]
def set_loan_repayment(self):
self.set('loans', [])
diff --git a/erpnext/hr/doctype/salary_structure/test_salary_structure.py b/erpnext/hr/doctype/salary_structure/test_salary_structure.py
index 848c3df57ab..f67a189ee71 100644
--- a/erpnext/hr/doctype/salary_structure/test_salary_structure.py
+++ b/erpnext/hr/doctype/salary_structure/test_salary_structure.py
@@ -25,7 +25,6 @@ class TestSalaryStructure(unittest.TestCase):
make_employee("test_employee@salary.com")
make_employee("test_employee_2@salary.com")
-
def make_holiday_list(self):
if not frappe.db.get_value("Holiday List", "Salary Structure Test Holiday List"):
holiday_list = frappe.get_doc({
@@ -38,6 +37,29 @@ class TestSalaryStructure(unittest.TestCase):
holiday_list.get_weekly_off_dates()
holiday_list.save()
+ def test_salary_structure_deduction_based_on_gross_pay(self):
+
+ emp = make_employee("test_employee_3@salary.com")
+
+ sal_struct = make_salary_structure("Salary Structure 2", "Monthly", dont_submit = True)
+
+ sal_struct.earnings = [sal_struct.earnings[0]]
+ sal_struct.earnings[0].amount_based_on_formula = 1
+ sal_struct.earnings[0].formula = "base"
+
+ sal_struct.deductions = [sal_struct.deductions[0]]
+
+ sal_struct.deductions[0].amount_based_on_formula = 1
+ sal_struct.deductions[0].condition = "gross_pay > 100"
+ sal_struct.deductions[0].formula = "gross_pay * 0.2"
+
+ sal_struct.submit()
+
+ assignment = create_salary_structure_assignment(emp, "Salary Structure 2")
+ ss = make_salary_slip(sal_struct.name, employee = emp)
+
+ self.assertEqual(assignment.base * 0.2, ss.deductions[0].amount)
+
def test_amount_totals(self):
frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 0)
sal_slip = frappe.get_value("Salary Slip", {"employee_name":"test_employee_2@salary.com"})
diff --git a/erpnext/hr/doctype/vehicle_log/test_vehicle_log.py b/erpnext/hr/doctype/vehicle_log/test_vehicle_log.py
index 35400b0ca83..3770da73fcf 100644
--- a/erpnext/hr/doctype/vehicle_log/test_vehicle_log.py
+++ b/erpnext/hr/doctype/vehicle_log/test_vehicle_log.py
@@ -8,25 +8,9 @@ import unittest
from frappe.utils import nowdate,flt, cstr,random_string
# test_records = frappe.get_test_records('Vehicle Log')
class TestVehicleLog(unittest.TestCase):
- def test_make_vehicle_log(self):
- license_plate=random_string(10).upper()
+ def test_make_vehicle_log_and_syncing_of_odometer_value(self):
employee_id=frappe.db.sql("""select name from `tabEmployee` order by modified desc limit 1""")[0][0]
- vehicle = frappe.get_doc({
- "doctype": "Vehicle",
- "license_plate": cstr(license_plate),
- "make": "Maruti",
- "model": "PCM",
- "last_odometer":5000,
- "acquisition_date":frappe.utils.nowdate(),
- "location": "Mumbai",
- "chassis_no": "1234ABCD",
- "uom": "Litre",
- "vehicle_value":frappe.utils.flt(500000)
- })
- try:
- vehicle.insert()
- except frappe.DuplicateEntryError:
- pass
+ license_plate = get_vehicle(employee_id)
vehicle_log = frappe.get_doc({
"doctype": "Vehicle Log",
"license_plate": cstr(license_plate),
@@ -36,5 +20,41 @@ class TestVehicleLog(unittest.TestCase):
"fuel_qty":frappe.utils.flt(50),
"price": frappe.utils.flt(500)
})
- vehicle_log.insert()
- vehicle_log.submit()
\ No newline at end of file
+ vehicle_log.save()
+ vehicle_log.submit()
+
+ #checking value of vehicle odometer value on submit.
+ vehicle = frappe.get_doc("Vehicle", license_plate)
+ self.assertEqual(vehicle.last_odometer, vehicle_log.odometer)
+
+ #checking value vehicle odometer on vehicle log cancellation.
+ last_odometer = vehicle_log.last_odometer
+ current_odometer = vehicle_log.odometer
+ distance_travelled = current_odometer - last_odometer
+
+ vehicle_log.cancel()
+ vehicle.reload()
+
+ self.assertEqual(vehicle.last_odometer, current_odometer - distance_travelled)
+
+
+def get_vehicle(employee_id):
+ license_plate=random_string(10).upper()
+ vehicle = frappe.get_doc({
+ "doctype": "Vehicle",
+ "license_plate": cstr(license_plate),
+ "make": "Maruti",
+ "model": "PCM",
+ "employee": employee_id,
+ "last_odometer":5000,
+ "acquisition_date":frappe.utils.nowdate(),
+ "location": "Mumbai",
+ "chassis_no": "1234ABCD",
+ "uom": "Litre",
+ "vehicle_value":frappe.utils.flt(500000)
+ })
+ try:
+ vehicle.insert()
+ except frappe.DuplicateEntryError:
+ pass
+ return license_plate
\ No newline at end of file
diff --git a/erpnext/hr/doctype/vehicle_log/vehicle_log.js b/erpnext/hr/doctype/vehicle_log/vehicle_log.js
index 7694cfed7cc..bdb37d2b734 100644
--- a/erpnext/hr/doctype/vehicle_log/vehicle_log.js
+++ b/erpnext/hr/doctype/vehicle_log/vehicle_log.js
@@ -2,29 +2,41 @@
// For license information, please see license.txt
frappe.ui.form.on("Vehicle Log", {
- refresh: function(frm,cdt,cdn) {
- var vehicle_log=frappe.model.get_doc(cdt,cdn);
- if (vehicle_log.license_plate) {
- frappe.call({
- method: "erpnext.hr.doctype.vehicle_log.vehicle_log.get_make_model",
- args: {
- license_plate: vehicle_log.license_plate
- },
- callback: function(r) {
- frappe.model.set_value(cdt, cdn, ("model"), r.message[0]);
- frappe.model.set_value(cdt, cdn, ("make"), r.message[1]);
- }
- })
+ refresh: function(frm) {
+
+ if(frm.doc.license_plate && frm.doc.__islocal){
+ frm.events.set_vehicle_details(frm);
}
if(frm.doc.docstatus == 1) {
frm.add_custom_button(__('Expense Claim'), function() {
- frm.events.expense_claim(frm)
+ frm.events.expense_claim(frm);
}, __('Create'));
frm.page.set_inner_btn_group_as_primary(__('Create'));
}
},
+ license_plate: function(frm) {
+ if(frm.doc.license_plate){
+ frm.events.set_vehicle_details(frm);
+ }
+ },
+
+ set_vehicle_details: function(frm) {
+ frappe.call({
+ method: "erpnext.hr.doctype.vehicle_log.vehicle_log.get_make_model",
+ args: {
+ license_plate: frm.doc.license_plate
+ },
+ callback: function(r) {
+ frappe.model.set_value(cur_frm.doctype, cur_frm.docname, "make", r.message[0]);
+ frappe.model.set_value(cur_frm.doctype, cur_frm.docname, "model", r.message[1]);
+ frappe.model.set_value(cur_frm.doctype, cur_frm.docname, "last_odometer", r.message[2]);
+ frappe.model.set_value(cur_frm.doctype, cur_frm.docname, "employee", r.message[3]);
+ }
+ });
+ },
+
expense_claim: function(frm){
frappe.call({
method: "erpnext.hr.doctype.vehicle_log.vehicle_log.make_expense_claim",
diff --git a/erpnext/hr/doctype/vehicle_log/vehicle_log.json b/erpnext/hr/doctype/vehicle_log/vehicle_log.json
index cde39e7ee44..52effffc064 100644
--- a/erpnext/hr/doctype/vehicle_log/vehicle_log.json
+++ b/erpnext/hr/doctype/vehicle_log/vehicle_log.json
@@ -1,706 +1,192 @@
{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "autoname": "naming_series:",
- "beta": 0,
- "creation": "2016-09-03 14:14:51.788550",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Document",
- "editable_grid": 1,
+ "actions": [],
+ "autoname": "naming_series:",
+ "creation": "2016-09-03 14:14:51.788550",
+ "doctype": "DocType",
+ "document_type": "Document",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "vehicle_section",
+ "naming_series",
+ "license_plate",
+ "employee",
+ "column_break_4",
+ "column_break_7",
+ "model",
+ "make",
+ "odometer_reading",
+ "date",
+ "odometer",
+ "column_break_12",
+ "last_odometer",
+ "refuelling_details",
+ "fuel_qty",
+ "price",
+ "column_break_15",
+ "supplier",
+ "invoice",
+ "service_details",
+ "service_detail",
+ "amended_from"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "vehicle_section",
- "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,
- "length": 0,
- "no_copy": 0,
- "options": "fa fa-user",
- "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
- },
+ "fieldname": "vehicle_section",
+ "fieldtype": "Section Break",
+ "options": "fa fa-user"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "",
- "fieldname": "naming_series",
- "fieldtype": "Select",
- "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": "Series",
- "length": 0,
- "no_copy": 1,
- "options": "HR-VLOG-.YYYY.-",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "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": 1,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "naming_series",
+ "fieldtype": "Select",
+ "label": "Series",
+ "no_copy": 1,
+ "options": "HR-VLOG-.YYYY.-",
+ "print_hide": 1,
+ "reqd": 1,
+ "set_only_once": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "license_plate",
- "fieldtype": "Link",
- "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": "License Plate",
- "length": 0,
- "no_copy": 0,
- "options": "Vehicle",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "license_plate",
+ "fieldtype": "Link",
+ "in_global_search": 1,
+ "in_list_view": 1,
+ "label": "License Plate",
+ "options": "Vehicle",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "employee",
- "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": 1,
- "label": "Employee",
- "length": 0,
- "no_copy": 0,
- "options": "Employee",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "employee",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Employee",
+ "options": "Employee",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_4",
- "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
- },
+ "fieldname": "column_break_4",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_7",
- "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
- },
+ "fieldname": "column_break_7",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "model",
- "fieldtype": "Read Only",
- "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": "Model",
- "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
- },
+ "fieldname": "model",
+ "fieldtype": "Read Only",
+ "label": "Model"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "make",
- "fieldtype": "Read Only",
- "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": "Make",
- "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
- },
+ "fieldname": "make",
+ "fieldtype": "Read Only",
+ "label": "Make"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "odometer_reading",
- "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": "Odometer Reading",
- "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
- },
+ "fieldname": "odometer_reading",
+ "fieldtype": "Section Break",
+ "label": "Odometer Reading"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "date",
- "fieldtype": "Date",
- "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": "Date",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "date",
+ "fieldtype": "Date",
+ "label": "Date",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "odometer",
- "fieldtype": "Int",
- "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": "Odometer",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "odometer",
+ "fieldtype": "Int",
+ "label": "Current Odometer value ",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 1,
- "columns": 0,
- "fieldname": "refuelling_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": "Refuelling Details",
- "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
- },
+ "collapsible": 1,
+ "fieldname": "refuelling_details",
+ "fieldtype": "Section Break",
+ "label": "Refuelling Details"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "fuel_qty",
- "fieldtype": "Float",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Fuel Qty",
- "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
- },
+ "fieldname": "fuel_qty",
+ "fieldtype": "Float",
+ "label": "Fuel Qty"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "price",
- "fieldtype": "Currency",
- "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": "Fuel Price",
- "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
- },
+ "fieldname": "price",
+ "fieldtype": "Currency",
+ "label": "Fuel Price"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_15",
- "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
- },
+ "fieldname": "column_break_15",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "supplier",
- "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": "Supplier",
- "length": 0,
- "no_copy": 0,
- "options": "Supplier",
- "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
- },
+ "fieldname": "supplier",
+ "fieldtype": "Link",
+ "label": "Supplier",
+ "options": "Supplier"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "invoice",
- "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": "Invoice Ref",
- "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
- },
+ "fieldname": "invoice",
+ "fieldtype": "Data",
+ "label": "Invoice Ref"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 1,
- "columns": 0,
- "fieldname": "service_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": "Service Details",
- "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
- },
+ "collapsible": 1,
+ "fieldname": "service_details",
+ "fieldtype": "Section Break",
+ "label": "Service Details"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "service_detail",
- "fieldtype": "Table",
- "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": "Service Detail",
- "length": 0,
- "no_copy": 0,
- "options": "Vehicle Service",
- "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
- },
+ "fieldname": "service_detail",
+ "fieldtype": "Table",
+ "label": "Service Detail",
+ "options": "Vehicle Service"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "amended_from",
- "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": "Amended From",
- "length": 0,
- "no_copy": 1,
- "options": "Vehicle Log",
- "permlevel": 0,
- "print_hide": 1,
- "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,
- "translatable": 0,
- "unique": 0
+ "fieldname": "amended_from",
+ "fieldtype": "Link",
+ "label": "Amended From",
+ "no_copy": 1,
+ "options": "Vehicle Log",
+ "print_hide": 1,
+ "read_only": 1
+ },
+ {
+ "fieldname": "last_odometer",
+ "fieldtype": "Int",
+ "label": "last Odometer Value ",
+ "read_only": 1,
+ "reqd": 1
+ },
+ {
+ "fieldname": "column_break_12",
+ "fieldtype": "Column Break"
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 1,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2018-08-21 14:44:51.131186",
- "modified_by": "Administrator",
- "module": "HR",
- "name": "Vehicle Log",
- "name_case": "",
- "owner": "Administrator",
+ ],
+ "is_submittable": 1,
+ "links": [],
+ "modified": "2020-01-28 12:43:34.419647",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Vehicle Log",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 0,
- "cancel": 1,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Fleet Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 1,
+ "cancel": 1,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Fleet Manager",
+ "share": 1,
+ "submit": 1,
"write": 1
}
- ],
- "quick_entry": 1,
- "read_only": 0,
- "read_only_onload": 0,
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "",
- "track_changes": 1,
- "track_seen": 0,
- "track_views": 0
+ ],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/vehicle_log/vehicle_log.py b/erpnext/hr/doctype/vehicle_log/vehicle_log.py
index df633611be8..12cc1dd03a6 100644
--- a/erpnext/hr/doctype/vehicle_log/vehicle_log.py
+++ b/erpnext/hr/doctype/vehicle_log/vehicle_log.py
@@ -11,22 +11,33 @@ from frappe.model.document import Document
class VehicleLog(Document):
def validate(self):
- last_odometer=frappe.db.get_value("Vehicle", self.license_plate, "last_odometer")
- if flt(self.odometer) < flt(last_odometer):
- frappe.throw(_("Current Odometer reading entered should be greater than initial Vehicle Odometer {0}").format(last_odometer))
+ if flt(self.odometer) < flt(self.last_odometer):
+ frappe.throw(_("Current Odometer reading entered should be greater than initial Vehicle Odometer {0}").format(self.last_odometer))
for service_detail in self.service_detail:
if (service_detail.service_item or service_detail.type or service_detail.frequency or service_detail.expense_amount):
if not (service_detail.service_item and service_detail.type and service_detail.frequency and service_detail.expense_amount):
frappe.throw(_("Service Item,Type,frequency and expense amount are required"))
+ def before_insert(self):
+ model_details = get_make_model(self.license_plate)
+ self.make = model_details[0]
+ self.model = model_details[1]
+ self.last_odometer = model_details[2]
+ self.employee = model_details[3]
+
def on_submit(self):
- frappe.db.sql("update `tabVehicle` set last_odometer=%s where license_plate=%s",
- (self.odometer, self.license_plate))
+ frappe.db.set_value("Vehicle", self.license_plate, "last_odometer", self.odometer)
+
+ def on_cancel(self):
+ distance_travelled = self.odometer - self.last_odometer
+ if(distance_travelled > 0):
+ updated_odometer_value = int(frappe.db.get_value("Vehicle", self.license_plate, "last_odometer")) - distance_travelled
+ frappe.db.set_value("Vehicle", self.license_plate, "last_odometer", updated_odometer_value)
@frappe.whitelist()
def get_make_model(license_plate):
vehicle=frappe.get_doc("Vehicle",license_plate)
- return (vehicle.make,vehicle.model)
+ return (vehicle.make, vehicle.model, vehicle.last_odometer, vehicle.employee)
@frappe.whitelist()
def make_expense_claim(docname):
diff --git a/erpnext/hr/report/monthly_attendance_sheet/monthly_attendance_sheet.py b/erpnext/hr/report/monthly_attendance_sheet/monthly_attendance_sheet.py
index 1e9c83bf3e6..aca3a175057 100644
--- a/erpnext/hr/report/monthly_attendance_sheet/monthly_attendance_sheet.py
+++ b/erpnext/hr/report/monthly_attendance_sheet/monthly_attendance_sheet.py
@@ -13,7 +13,7 @@ def execute(filters=None):
conditions, filters = get_conditions(filters)
columns = get_columns(filters)
att_map = get_attendance_list(conditions, filters)
- emp_map = get_employee_details()
+ emp_map = get_employee_details(filters)
holiday_list = [emp_map[d]["holiday_list"] for d in emp_map if emp_map[d]["holiday_list"]]
default_holiday_list = frappe.get_cached_value('Company', filters.get("company"), "default_holiday_list")
@@ -131,10 +131,10 @@ def get_conditions(filters):
return conditions, filters
-def get_employee_details():
+def get_employee_details(filters):
emp_map = frappe._dict()
for d in frappe.db.sql("""select name, employee_name, designation, department, branch, company,
- holiday_list from tabEmployee""", as_dict=1):
+ holiday_list from tabEmployee where company = "%s" """ % (filters.get("company")), as_dict=1):
emp_map.setdefault(d.name, d)
return emp_map
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 7f7ffa14bfa..b2a0b18db5e 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -487,6 +487,14 @@ class BOM(WebsiteGenerator):
self.scrap_material_cost = total_sm_cost
self.base_scrap_material_cost = base_total_sm_cost
+ def update_new_bom(self, old_bom, new_bom, rate):
+ for d in self.get("items"):
+ if d.bom_no != old_bom: continue
+
+ d.bom_no = new_bom
+ d.rate = rate
+ d.amount = (d.stock_qty or d.qty) * rate
+
def update_exploded_items(self):
""" Update Flat BOM, following will be correct data"""
self.get_exploded_items()
diff --git a/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py b/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py
index 31a9fdb28ab..2758a423716 100644
--- a/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py
+++ b/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py
@@ -14,10 +14,13 @@ import click
class BOMUpdateTool(Document):
def replace_bom(self):
self.validate_bom()
- self.update_new_bom()
+
+ unit_cost = get_new_bom_unit_cost(self.new_bom)
+ self.update_new_bom(unit_cost)
+
frappe.cache().delete_key('bom_children')
bom_list = self.get_parent_boms(self.new_bom)
- updated_bom = []
+
with click.progressbar(bom_list) as bom_list:
pass
for bom in bom_list:
@@ -26,7 +29,9 @@ class BOMUpdateTool(Document):
# this is only used for versioning and we do not want
# to make separate db calls by using load_doc_before_save
# which proves to be expensive while doing bulk replace
- bom_obj._doc_before_save = bom_obj.as_dict()
+ bom_obj._doc_before_save = bom_obj
+ bom_obj.update_new_bom(self.current_bom, self.new_bom, unit_cost)
+ bom_obj.update_exploded_items()
bom_obj.calculate_cost()
bom_obj.update_parent_cost()
bom_obj.db_update()
@@ -43,14 +48,10 @@ class BOMUpdateTool(Document):
!= frappe.db.get_value("BOM", self.new_bom, "item"):
frappe.throw(_("The selected BOMs are not for the same item"))
- def update_new_bom(self):
- new_bom_unitcost = frappe.db.sql("""SELECT `total_cost`/`quantity`
- FROM `tabBOM` WHERE name = %s""", self.new_bom)
- new_bom_unitcost = flt(new_bom_unitcost[0][0]) if new_bom_unitcost else 0
-
+ def update_new_bom(self, unit_cost):
frappe.db.sql("""update `tabBOM Item` set bom_no=%s,
rate=%s, amount=stock_qty*%s where bom_no = %s and docstatus < 2 and parenttype='BOM'""",
- (self.new_bom, new_bom_unitcost, new_bom_unitcost, self.current_bom))
+ (self.new_bom, unit_cost, unit_cost, self.current_bom))
def get_parent_boms(self, bom, bom_list=[]):
data = frappe.db.sql("""SELECT DISTINCT parent FROM `tabBOM Item`
@@ -65,12 +66,18 @@ class BOMUpdateTool(Document):
return list(set(bom_list))
+def get_new_bom_unit_cost(bom):
+ new_bom_unitcost = frappe.db.sql("""SELECT `total_cost`/`quantity`
+ FROM `tabBOM` WHERE name = %s""", bom)
+
+ return flt(new_bom_unitcost[0][0]) if new_bom_unitcost else 0
+
@frappe.whitelist()
def enqueue_replace_bom(args):
if isinstance(args, string_types):
args = json.loads(args)
- frappe.enqueue("erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.replace_bom", args=args, timeout=4000)
+ frappe.enqueue("erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.replace_bom", args=args, timeout=40000)
frappe.msgprint(_("Queued for replacing the BOM. It may take a few minutes."))
@frappe.whitelist()
diff --git a/erpnext/manufacturing/doctype/work_order/test_work_order.py b/erpnext/manufacturing/doctype/work_order/test_work_order.py
index ea2e7a96e1d..f917b098688 100644
--- a/erpnext/manufacturing/doctype/work_order/test_work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/test_work_order.py
@@ -14,6 +14,7 @@ from erpnext.stock.utils import get_bin
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
from erpnext.stock.doctype.item.test_item import make_item
from erpnext.manufacturing.doctype.production_plan.test_production_plan import make_bom
+from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
class TestWorkOrder(unittest.TestCase):
def setUp(self):
@@ -82,6 +83,37 @@ class TestWorkOrder(unittest.TestCase):
wo_order.set_work_order_operations()
self.assertEqual(wo_order.planned_operating_cost, cost*2)
+ def test_resered_qty_for_partial_completion(self):
+ item = "_Test Item"
+ warehouse = create_warehouse("Test Warehouse for reserved_qty - _TC")
+
+ bin1_at_start = get_bin(item, warehouse)
+
+ # reset to correct value
+ bin1_at_start.update_reserved_qty_for_production()
+
+ wo_order = make_wo_order_test_record(item="_Test FG Item", qty=2,
+ source_warehouse=warehouse, skip_transfer=1)
+
+ bin1_on_submit = get_bin(item, warehouse)
+
+ # reserved qty for production is updated
+ self.assertEqual(cint(bin1_at_start.reserved_qty_for_production) + 2,
+ cint(bin1_on_submit.reserved_qty_for_production))
+
+ test_stock_entry.make_stock_entry(item_code="_Test Item",
+ target=warehouse, qty=100, basic_rate=100)
+ test_stock_entry.make_stock_entry(item_code="_Test Item Home Desktop 100",
+ target=warehouse, qty=100, basic_rate=100)
+
+ s = frappe.get_doc(make_stock_entry(wo_order.name, "Manufacture", 1))
+ s.submit()
+
+ bin1_at_completion = get_bin(item, warehouse)
+
+ self.assertEqual(cint(bin1_at_completion.reserved_qty_for_production),
+ cint(bin1_on_submit.reserved_qty_for_production) - 1)
+
def test_production_item(self):
wo_order = make_wo_order_test_record(item="_Test FG Item", qty=1, do_not_save=True)
frappe.db.set_value("Item", "_Test FG Item", "end_of_life", "2000-1-1")
@@ -368,7 +400,7 @@ def make_wo_order_test_record(**args):
wo_order.company = args.company or "_Test Company"
wo_order.stock_uom = args.stock_uom or "_Test UOM"
wo_order.use_multi_level_bom=0
- wo_order.skip_transfer=1
+ wo_order.skip_transfer=args.skip_transfer or 0
wo_order.get_items_and_operations_from_bom()
wo_order.sales_order = args.sales_order or None
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py
index b4dc3a55699..28bcc2e0f9c 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/work_order.py
@@ -429,6 +429,9 @@ class WorkOrder(Document):
update bin reserved_qty_for_production
called from Stock Entry for production, after submit, cancel
'''
+ # calculate consumed qty based on submitted stock entries
+ self.update_consumed_qty_for_required_items()
+
if self.docstatus==1:
# calculate transferred qty based on submitted stock entries
self.update_transaferred_qty_for_required_items()
@@ -436,9 +439,6 @@ class WorkOrder(Document):
# update in bin
self.update_reserved_qty_for_production()
- # calculate consumed qty based on submitted stock entries
- self.update_consumed_qty_for_required_items()
-
def update_reserved_qty_for_production(self, items=None):
'''update reserved_qty_for_production in bins'''
for d in self.required_items:
diff --git a/erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py b/erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py
index be016ad9a47..f7b407b7922 100644
--- a/erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py
+++ b/erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py
@@ -4,6 +4,7 @@
from __future__ import unicode_literals
import frappe
from frappe import _
+from frappe.utils.data import comma_and
def execute(filters=None):
# if not filters: filters = {}
@@ -13,35 +14,36 @@ def execute(filters=None):
data = get_bom_stock(filters)
qty_to_make = filters.get("qty_to_make")
+ manufacture_details = get_manufacturer_records()
for row in data:
- item_map = get_item_details(row.item_code)
reqd_qty = qty_to_make * row.actual_qty
last_pur_price = frappe.db.get_value("Item", row.item_code, "last_purchase_rate")
- if row.to_build > 0:
- diff_qty = row.to_build - reqd_qty
- summ_data.append([row.item_code, row.description, item_map[row.item_code]["manufacturer"], item_map[row.item_code]["manufacturer_part_no"], row.actual_qty, row.to_build, reqd_qty, diff_qty, last_pur_price])
- else:
- diff_qty = 0 - reqd_qty
- summ_data.append([row.item_code, row.description, item_map[row.item_code]["manufacturer"], item_map[row.item_code]["manufacturer_part_no"], row.actual_qty, "0.000", reqd_qty, diff_qty, last_pur_price])
+ summ_data.append(get_report_data(last_pur_price, reqd_qty, row, manufacture_details))
return columns, summ_data
+def get_report_data(last_pur_price, reqd_qty, row, manufacture_details):
+ to_build = row.to_build if row.to_build > 0 else 0
+ diff_qty = to_build - reqd_qty
+ return [row.item_code, row.description,
+ comma_and(manufacture_details.get(row.item_code, {}).get('manufacturer', []), add_quotes=False),
+ comma_and(manufacture_details.get(row.item_code, {}).get('manufacturer_part', []), add_quotes=False),
+ row.actual_qty, str(to_build),
+ reqd_qty, diff_qty, last_pur_price]
+
def get_columns():
"""return columns"""
columns = [
_("Item") + ":Link/Item:100",
_("Description") + "::150",
- _("Manufacturer") + "::100",
- _("Manufacturer Part Number") + "::100",
+ _("Manufacturer") + "::250",
+ _("Manufacturer Part Number") + "::250",
_("Qty") + ":Float:50",
_("Stock Qty") + ":Float:100",
_("Reqd Qty")+ ":Float:100",
_("Diff Qty")+ ":Float:100",
_("Last Purchase Price")+ ":Float:100",
-
-
]
-
return columns
def get_bom_stock(filters):
@@ -85,7 +87,12 @@ def get_bom_stock(filters):
GROUP BY bom_item.item_code""".format(qty_field=qty_field, table=table, conditions=conditions, bom=bom), as_dict=1)
-def get_item_details(item_code):
- items = frappe.db.sql("""select it.item_group, it.item_name, it.stock_uom, it.name, it.brand, it.description, it.manufacturer_part_no, it.manufacturer from tabItem it where it.item_code = %s""", item_code, as_dict=1)
+def get_manufacturer_records():
+ details = frappe.get_list('Item Manufacturer', fields = ["manufacturer", "manufacturer_part_no, parent"])
+ manufacture_details = frappe._dict()
+ for detail in details:
+ dic = manufacture_details.setdefault(detail.get('parent'), {})
+ dic.setdefault('manufacturer', []).append(detail.get('manufacturer'))
+ dic.setdefault('manufacturer_part', []).append(detail.get('manufacturer_part_no'))
- return dict((d.name, d) for d in items)
+ return manufacture_details
\ No newline at end of file
diff --git a/erpnext/portal/product_configurator/utils.py b/erpnext/portal/product_configurator/utils.py
index ce507a39486..327a128068f 100644
--- a/erpnext/portal/product_configurator/utils.py
+++ b/erpnext/portal/product_configurator/utils.py
@@ -188,7 +188,9 @@ def get_attributes_and_values(item_code):
def get_numeric_values():
attribute_values_list = []
- numeric_attributes = frappe.get_list("Item Attribute", fields=['name', 'from_range', 'to_range', 'increment'], filters={"numeric_values": 1})
+ numeric_attributes = frappe.db.get_all("Item Attribute",
+ fields=['name', 'from_range', 'to_range', 'increment'],
+ filters={"numeric_values": 1})
for attribute in numeric_attributes:
from_range = attribute["from_range"]
to_range = attribute['to_range'] + attribute['increment']
diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py
index f2ba80f096f..7cf4150298c 100755
--- a/erpnext/projects/doctype/task/task.py
+++ b/erpnext/projects/doctype/task/task.py
@@ -212,10 +212,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']]})
+ tasks = frappe.get_all("Task", filters={"status": ["not in", ["Cancelled", "Completed"]]}, fields=["name", "status", "review_date"])
for task in tasks:
- 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()):
+ if task.status == "Pending Review":
+ if getdate(task.review_date) > getdate(today()):
continue
frappe.get_doc("Task", task.name).update_status()
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index 3f444f83879..98986f8bf1b 100755
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -439,12 +439,13 @@ erpnext.utils.update_child_items = function(opts) {
const dialog = new frappe.ui.Dialog({
title: __("Update Items"),
fields: [
- {fieldtype:'Section Break', label: __('Items')},
{
fieldname: "trans_items",
fieldtype: "Table",
+ label: "Items",
cannot_add_rows: cannot_add_row,
in_place_edit: true,
+ reqd: 1,
data: this.data,
get_data: () => {
return this.data;
diff --git a/erpnext/public/js/utils/dimension_tree_filter.js b/erpnext/public/js/utils/dimension_tree_filter.js
index 7abe4a7aab1..8b6de0f5179 100644
--- a/erpnext/public/js/utils/dimension_tree_filter.js
+++ b/erpnext/public/js/utils/dimension_tree_filter.js
@@ -35,11 +35,13 @@ erpnext.doctypes_with_dimensions.forEach((doctype) => {
}
}
- if (frm.doc.items && frm.doc.items.length) {
+ if (frm.doc.items && frm.doc.items.length && frm.doc.docstatus === 0
+ && (!frm.doc.items[0][dimension['fieldname']])) {
frm.doc.items[0][dimension['fieldname']] = erpnext.default_dimensions[frm.doc.company][dimension['document_type']];
}
- if (frm.doc.accounts && frm.doc.accounts.length) {
+ if (frm.doc.accounts && frm.doc.accounts.length && frm.doc.docstatus === 0
+ && (!frm.doc.items[0][dimension['fieldname']])) {
frm.doc.accounts[0][dimension['fieldname']] = erpnext.default_dimensions[frm.doc.company][dimension['document_type']];
}
}
diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py
index 0f9156a6b4c..831985fc7cc 100644
--- a/erpnext/regional/india/utils.py
+++ b/erpnext/regional/india/utils.py
@@ -464,7 +464,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 = '{0}'""".format(company))
+ `tabDynamic Link`.link_name = %(company)s""", {"company": company})
return company_gstins
def get_address_details(data, doc, company_address, billing_address):
diff --git a/erpnext/regional/report/gst_itemised_purchase_register/gst_itemised_purchase_register.py b/erpnext/regional/report/gst_itemised_purchase_register/gst_itemised_purchase_register.py
index 3ce2547b20f..b5948f9952d 100644
--- a/erpnext/regional/report/gst_itemised_purchase_register/gst_itemised_purchase_register.py
+++ b/erpnext/regional/report/gst_itemised_purchase_register/gst_itemised_purchase_register.py
@@ -13,9 +13,9 @@ def execute(filters=None):
dict(fieldtype='Data', label='GST Category', fieldname="gst_category", width=120),
dict(fieldtype='Data', label='Export Type', fieldname="export_type", width=120),
dict(fieldtype='Data', label='E-Commerce GSTIN', fieldname="ecommerce_gstin", width=130),
- dict(fieldtype='Data', label='HSN Code', fieldname="hsn_code", width=120),
- dict(fieldtype='Data', label='Supplier Invoice No', fieldname="supplier_invoice_no", width=120),
- dict(fieldtype='Date', label='Supplier Invoice Date', fieldname="supplier_invoice_date", width=100)
+ dict(fieldtype='Data', label='HSN Code', fieldname="gst_hsn_code", width=120),
+ dict(fieldtype='Data', label='Supplier Invoice No', fieldname="bill_no", width=120),
+ dict(fieldtype='Date', label='Supplier Invoice Date', fieldname="bill_date", width=100)
], additional_query_columns=[
'supplier_gstin',
'company_gstin',
diff --git a/erpnext/regional/report/gst_itemised_sales_register/gst_itemised_sales_register.py b/erpnext/regional/report/gst_itemised_sales_register/gst_itemised_sales_register.py
index ab523e74e67..e13f509f475 100644
--- a/erpnext/regional/report/gst_itemised_sales_register/gst_itemised_sales_register.py
+++ b/erpnext/regional/report/gst_itemised_sales_register/gst_itemised_sales_register.py
@@ -15,7 +15,7 @@ def execute(filters=None):
dict(fieldtype='Data', label='GST Category', fieldname="gst_category", width=120),
dict(fieldtype='Data', label='Export Type', fieldname="export_type", width=120),
dict(fieldtype='Data', label='E-Commerce GSTIN', fieldname="ecommerce_gstin", width=130),
- dict(fieldtype='Data', label='HSN Code', fieldname="hsn_code", width=120)
+ dict(fieldtype='Data', label='HSN Code', fieldname="gst_hsn_code", width=120)
], additional_query_columns=[
'customer_gstin',
'billing_address_gstin',
diff --git a/erpnext/regional/turkey/setup.py b/erpnext/regional/turkey/setup.py
new file mode 100644
index 00000000000..ebf3b2bee1f
--- /dev/null
+++ b/erpnext/regional/turkey/setup.py
@@ -0,0 +1,4 @@
+from __future__ import unicode_literals
+
+def setup(company=None, patch=True):
+ pass
\ No newline at end of file
diff --git a/erpnext/selling/doctype/product_bundle_item/product_bundle_item.json b/erpnext/selling/doctype/product_bundle_item/product_bundle_item.json
index 38f51dead49..dc071e4d65e 100644
--- a/erpnext/selling/doctype/product_bundle_item/product_bundle_item.json
+++ b/erpnext/selling/doctype/product_bundle_item/product_bundle_item.json
@@ -1,189 +1,76 @@
{
- "allow_copy": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "beta": 0,
- "creation": "2013-05-23 16:55:51",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
+ "actions": [],
+ "creation": "2013-05-23 16:55:51",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "item_code",
+ "qty",
+ "description",
+ "rate",
+ "uom"
+ ],
"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": 1,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Item",
- "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": 1,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "fieldname": "item_code",
+ "fieldtype": "Link",
+ "in_global_search": 1,
+ "in_list_view": 1,
+ "label": "Item",
+ "oldfieldname": "item_code",
+ "oldfieldtype": "Link",
+ "options": "Item",
+ "reqd": 1
+ },
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "qty",
- "fieldtype": "Float",
- "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": "Qty",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "qty",
- "oldfieldtype": "Currency",
- "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": "qty",
+ "fieldtype": "Float",
+ "in_list_view": 1,
+ "label": "Qty",
+ "oldfieldname": "qty",
+ "oldfieldtype": "Currency",
+ "reqd": 1
+ },
{
- "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": "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": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "fieldname": "description",
+ "fieldtype": "Text Editor",
+ "in_list_view": 1,
+ "label": "Description",
+ "oldfieldname": "description",
+ "oldfieldtype": "Text",
+ "print_width": "300px"
+ },
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "rate",
- "fieldtype": "Float",
- "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": "Rate",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "rate",
- "oldfieldtype": "Currency",
- "permlevel": 0,
- "print_hide": 1,
- "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": "rate",
+ "fieldtype": "Float",
+ "hidden": 1,
+ "label": "Rate",
+ "oldfieldname": "rate",
+ "oldfieldtype": "Currency",
+ "print_hide": 1
+ },
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "uom",
- "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": "UOM",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "uom",
- "oldfieldtype": "Link",
- "options": "UOM",
- "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
+ "fieldname": "uom",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "UOM",
+ "oldfieldname": "uom",
+ "oldfieldtype": "Link",
+ "options": "UOM",
+ "read_only": 1
}
- ],
- "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-20 13:24:05.633546",
- "modified_by": "Administrator",
- "module": "Selling",
- "name": "Product Bundle Item",
- "owner": "Administrator",
- "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,
+ "links": [],
+ "modified": "2020-02-28 14:06:05.725655",
+ "modified_by": "Administrator",
+ "module": "Selling",
+ "name": "Product Bundle Item",
+ "owner": "Administrator",
+ "permissions": [],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
}
\ No newline at end of file
diff --git a/erpnext/selling/doctype/quotation_item/quotation_item.json b/erpnext/selling/doctype/quotation_item/quotation_item.json
index a299b8809ab..3ff5555e827 100644
--- a/erpnext/selling/doctype/quotation_item/quotation_item.json
+++ b/erpnext/selling/doctype/quotation_item/quotation_item.json
@@ -1,4 +1,5 @@
{
+ "actions": [],
"creation": "2013-03-07 11:42:57",
"doctype": "DocType",
"document_type": "Document",
@@ -163,6 +164,7 @@
"oldfieldname": "stock_uom",
"oldfieldtype": "Data",
"options": "UOM",
+ "print_hide": 1,
"print_width": "100px",
"read_only": 1,
"width": "100px"
@@ -176,7 +178,6 @@
"fieldtype": "Link",
"label": "UOM",
"options": "UOM",
- "print_hide": 1,
"reqd": 1
},
{
@@ -382,6 +383,7 @@
"read_only": 1
},
{
+ "default": "0",
"fieldname": "is_free_item",
"fieldtype": "Check",
"label": "Is Free Item",
@@ -517,6 +519,7 @@
},
{
"allow_on_submit": 1,
+ "default": "0",
"fieldname": "page_break",
"fieldtype": "Check",
"label": "Page Break",
@@ -574,7 +577,8 @@
],
"idx": 1,
"istable": 1,
- "modified": "2019-05-01 17:39:14.228141",
+ "links": [],
+ "modified": "2020-03-05 14:18:58.783751",
"modified_by": "Administrator",
"module": "Selling",
"name": "Quotation Item",
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 4a365004da8..9e4a71d60e5 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -645,7 +645,6 @@ 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")
diff --git a/erpnext/selling/doctype/sales_order_item/sales_order_item.json b/erpnext/selling/doctype/sales_order_item/sales_order_item.json
index 317f284eff3..c95f236ebba 100644
--- a/erpnext/selling/doctype/sales_order_item/sales_order_item.json
+++ b/erpnext/selling/doctype/sales_order_item/sales_order_item.json
@@ -209,7 +209,6 @@
"fieldtype": "Link",
"label": "UOM",
"options": "UOM",
- "print_hide": 1,
"reqd": 1
},
{
@@ -758,7 +757,8 @@
],
"idx": 1,
"istable": 1,
- "modified": "2019-12-11 18:06:26.238169",
+ "links": [],
+ "modified": "2020-03-05 14:20:28.085117",
"modified_by": "Administrator",
"module": "Selling",
"name": "Sales Order Item",
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index ff3515485c4..c3fd3566578 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -416,8 +416,13 @@ def install_country_fixtures(company):
company_doc = frappe.get_doc("Company", company)
path = frappe.get_app_path('erpnext', 'regional', frappe.scrub(company_doc.country))
if os.path.exists(path.encode("utf-8")):
- frappe.get_attr("erpnext.regional.{0}.setup.setup"
- .format(frappe.scrub(company_doc.country)))(company_doc, False)
+ try:
+ module_name = "erpnext.regional.{0}.setup.setup".format(frappe.scrub(company_doc.country))
+ frappe.get_attr(module_name)(company_doc, False)
+ except Exception as e:
+ frappe.log_error(str(e), frappe.get_traceback())
+ frappe.throw(_("Failed to setup defaults for country {0}. Please contact support@erpnext.com").format(frappe.bold(company_doc.country)))
+
def update_company_current_month_sales(company):
current_month_year = formatdate(today(), "MM-yyyy")
diff --git a/erpnext/setup/doctype/company/delete_company_transactions.py b/erpnext/setup/doctype/company/delete_company_transactions.py
index 3052191943c..9979bc51e3a 100644
--- a/erpnext/setup/doctype/company/delete_company_transactions.py
+++ b/erpnext/setup/doctype/company/delete_company_transactions.py
@@ -106,11 +106,11 @@ def delete_lead_addresses(company_name):
frappe.db.sql("""update tabCustomer set lead_name=NULL where lead_name in ({leads})""".format(leads=",".join(leads)))
def delete_communications(doctype, company_name, company_fieldname):
-
+
refrence_docs = frappe.get_all(doctype, filters={company_fieldname:company_name})
reference_doctype_names = [r.name for r in refrence_docs]
communications = frappe.get_all("Communication", filters={"reference_doctype":doctype,"reference_name":["in",reference_doctype_names]})
communication_names = [c.name for c in communications]
- frappe.delete_doc("Communication",communication_names)
+ frappe.delete_doc("Communication", communication_names, ignore_permissions=True)
diff --git a/erpnext/setup/doctype/company/test_company.py b/erpnext/setup/doctype/company/test_company.py
index 524f3eb5b17..fe13d63955f 100644
--- a/erpnext/setup/doctype/company/test_company.py
+++ b/erpnext/setup/doctype/company/test_company.py
@@ -9,7 +9,7 @@ from frappe import _
from frappe.utils import random_string
from erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts import get_charts_for_country
-test_ignore = ["Account", "Cost Center", "Payment Terms Template", "Salary Component"]
+test_ignore = ["Account", "Cost Center", "Payment Terms Template", "Salary Component", "Warehouse"]
test_dependencies = ["Fiscal Year"]
test_records = frappe.get_test_records('Company')
diff --git a/erpnext/setup/doctype/sales_person/sales_person.js b/erpnext/setup/doctype/sales_person/sales_person.js
index 9ff37fa4e83..89ca4a9dd74 100644
--- a/erpnext/setup/doctype/sales_person/sales_person.js
+++ b/erpnext/setup/doctype/sales_person/sales_person.js
@@ -19,6 +19,11 @@ frappe.ui.form.on('Sales Person', {
}
}
};
+
+ frm.make_methods = {
+ 'Sales Order': () => frappe.new_doc("Sales Order")
+ .then(() => frm.add_child("sales_team", {"sales_person": frm.doc.name}))
+ }
}
});
diff --git a/erpnext/setup/utils.py b/erpnext/setup/utils.py
index d1c206d8b1d..ffd5ab1e840 100644
--- a/erpnext/setup/utils.py
+++ b/erpnext/setup/utils.py
@@ -141,6 +141,6 @@ def insert_record(records):
raise
def welcome_email():
- site_name = get_default_company()
- title = _("Welcome to {0}".format(site_name))
+ site_name = get_default_company() or "ERPNext"
+ title = _("Welcome to {0}").format(site_name)
return title
diff --git a/erpnext/stock/doctype/bin/bin.py b/erpnext/stock/doctype/bin/bin.py
index 97a84726da8..73b36e3d852 100644
--- a/erpnext/stock/doctype/bin/bin.py
+++ b/erpnext/stock/doctype/bin/bin.py
@@ -69,15 +69,21 @@ class Bin(Document):
'''Update qty reserved for production from Production Item tables
in open work orders'''
self.reserved_qty_for_production = frappe.db.sql('''
- select sum(item.required_qty - item.transferred_qty)
- from `tabWork Order` pro, `tabWork Order Item` item
- where
+ SELECT
+ CASE WHEN ifnull(skip_transfer, 0) = 0 THEN
+ SUM(item.required_qty - item.transferred_qty)
+ ELSE
+ SUM(item.required_qty - item.consumed_qty)
+ END
+ FROM `tabWork Order` pro, `tabWork Order Item` item
+ WHERE
item.item_code = %s
and item.parent = pro.name
and pro.docstatus = 1
and item.source_warehouse = %s
and pro.status not in ("Stopped", "Completed")
- and item.required_qty > item.transferred_qty''', (self.item_code, self.warehouse))[0][0]
+ and (item.required_qty > item.transferred_qty or item.required_qty > item.consumed_qty)
+ ''', (self.item_code, self.warehouse))[0][0]
self.set_projected_qty()
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 39aad2e0071..3f74b54ce80 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -413,7 +413,6 @@ 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")
diff --git a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
index af06daeabd3..a3386fce193 100644
--- a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
+++ b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
@@ -1,4 +1,5 @@
{
+ "actions": [],
"autoname": "hash",
"creation": "2013-04-22 13:15:44",
"doctype": "DocType",
@@ -80,6 +81,8 @@
"accounting_dimensions_section",
"cost_center",
"dimension_col_break",
+ "reason_for_return_section_break",
+ "reason_for_return",
"section_break_72",
"page_break"
],
@@ -180,6 +183,7 @@
"oldfieldname": "stock_uom",
"oldfieldtype": "Data",
"options": "UOM",
+ "print_hide": 1,
"print_width": "50px",
"read_only": 1,
"reqd": 1,
@@ -195,7 +199,6 @@
"in_list_view": 1,
"label": "UOM",
"options": "UOM",
- "print_hide": 1,
"reqd": 1
},
{
@@ -698,11 +701,26 @@
{
"fieldname": "dimension_col_break",
"fieldtype": "Column Break"
+ },
+ {
+ "depends_on": "eval:parent.is_return==1",
+ "fieldname": "reason_for_return",
+ "fieldtype": "Small Text",
+ "label": "Reason for Return",
+ "no_copy": 1
+ },
+ {
+ "default": "0",
+ "depends_on": "eval:parent.is_return==1",
+ "fieldname": "reason_for_return_section_break",
+ "fieldtype": "Section Break",
+ "label": "Reason For Return"
}
],
"idx": 1,
"istable": 1,
- "modified": "2019-05-25 22:08:27.452734",
+ "links": [],
+ "modified": "2020-03-06 14:18:33.131672",
"modified_by": "Administrator",
"module": "Stock",
"name": "Delivery Note Item",
@@ -710,4 +728,4 @@
"permissions": [],
"sort_field": "modified",
"sort_order": "DESC"
-}
\ No newline at end of file
+}
diff --git a/erpnext/stock/doctype/delivery_trip/delivery_trip.py b/erpnext/stock/doctype/delivery_trip/delivery_trip.py
index 77d322ed28d..209b1ef1468 100644
--- a/erpnext/stock/doctype/delivery_trip/delivery_trip.py
+++ b/erpnext/stock/doctype/delivery_trip/delivery_trip.py
@@ -238,7 +238,7 @@ class DeliveryTrip(Document):
try:
directions = maps_client.directions(**directions_data)
except Exception as e:
- frappe.throw(_(e))
+ frappe.throw(_(str(e)))
return directions[0] if directions else False
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index d2e04914017..cb0eb406df6 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -183,12 +183,17 @@ class Item(WebsiteGenerator):
# default warehouse, or Stores
for default in self.item_defaults or [frappe._dict({'company': frappe.defaults.get_defaults().company})]:
default_warehouse = (default.default_warehouse
- or frappe.db.get_single_value('Stock Settings', 'default_warehouse')
- or frappe.db.get_value('Warehouse', {'warehouse_name': _('Stores')}))
+ or frappe.db.get_single_value('Stock Settings', 'default_warehouse'))
+ if default_warehouse:
+ warehouse_company = frappe.db.get_value("Warehouse", default_warehouse, "company")
+
+ if not default_warehouse or warehouse_company != default.company:
+ default_warehouse = frappe.db.get_value('Warehouse',
+ {'warehouse_name': _('Stores'), 'company': default.company})
if default_warehouse:
stock_entry = make_stock_entry(item_code=self.name, target=default_warehouse, qty=self.opening_stock,
- rate=self.valuation_rate, company=default.company)
+ rate=self.valuation_rate, company=default.company)
stock_entry.add_comment("Comment", _("Opening Stock"))
diff --git a/erpnext/stock/doctype/item_alternative/item_alternative.py b/erpnext/stock/doctype/item_alternative/item_alternative.py
index 8e54539b18b..0c0d5b3271f 100644
--- a/erpnext/stock/doctype/item_alternative/item_alternative.py
+++ b/erpnext/stock/doctype/item_alternative/item_alternative.py
@@ -22,6 +22,21 @@ class ItemAlternative(Document):
if self.item_code == self.alternative_item_code:
frappe.throw(_("Alternative item must not be same as item code"))
+ item_meta = frappe.get_meta("Item")
+ fields = ["is_stock_item", "include_item_in_manufacturing","has_serial_no","has_batch_no"]
+ item_data = frappe.db.get_values("Item", self.item_code, fields, as_dict=1)
+ alternative_item_data = frappe.db.get_values("Item", self.alternative_item_code, fields, as_dict=1)
+
+ for field in fields:
+ if item_data[0].get(field) != alternative_item_data[0].get(field):
+ raise_exception, alert = [1, False] if field == "is_stock_item" else [0, True]
+
+ frappe.msgprint(_("The value of {0} differs between Items {1} and {2}") \
+ .format(frappe.bold(item_meta.get_label(field)),
+ frappe.bold(self.alternative_item_code),
+ frappe.bold(self.item_code)),
+ alert=alert, raise_exception=raise_exception)
+
def validate_duplicate(self):
if frappe.db.get_value("Item Alternative", {'item_code': self.item_code,
'alternative_item_code': self.alternative_item_code, 'name': ('!=', self.name)}):
diff --git a/erpnext/stock/doctype/item_price/item_price.json b/erpnext/stock/doctype/item_price/item_price.json
index 8456b584ca0..2e0ddfdaefc 100644
--- a/erpnext/stock/doctype/item_price/item_price.json
+++ b/erpnext/stock/doctype/item_price/item_price.json
@@ -10,7 +10,6 @@
"item_code",
"uom",
"packing_unit",
- "min_qty",
"column_break_17",
"item_name",
"brand",
@@ -63,13 +62,6 @@
"fieldtype": "Int",
"label": "Packing Unit"
},
- {
- "default": "1",
- "fieldname": "min_qty",
- "fieldtype": "Int",
- "in_list_view": 1,
- "label": "Minimum Qty "
- },
{
"fieldname": "column_break_17",
"fieldtype": "Column Break"
@@ -216,7 +208,7 @@
"icon": "fa fa-flag",
"idx": 1,
"links": [],
- "modified": "2019-12-31 03:11:09.702250",
+ "modified": "2020-02-28 14:21:25.580331",
"modified_by": "Administrator",
"module": "Stock",
"name": "Item Price",
@@ -251,6 +243,7 @@
}
],
"quick_entry": 1,
+ "sort_field": "modified",
"sort_order": "ASC",
"title_field": "item_name",
"track_changes": 1
diff --git a/erpnext/stock/doctype/item_price/test_records.json b/erpnext/stock/doctype/item_price/test_records.json
index 473bacb3c33..0a3d7e81985 100644
--- a/erpnext/stock/doctype/item_price/test_records.json
+++ b/erpnext/stock/doctype/item_price/test_records.json
@@ -4,7 +4,6 @@
"item_code": "_Test Item",
"price_list": "_Test Price List",
"price_list_rate": 100,
- "min_qty": 2,
"valid_from": "2017-04-18",
"valid_upto": "2017-04-26"
},
@@ -12,8 +11,7 @@
"doctype": "Item Price",
"item_code": "_Test Item",
"price_list": "_Test Price List Rest of the World",
- "price_list_rate": 10,
- "min_qty": 5
+ "price_list_rate": 10
},
{
"doctype": "Item Price",
@@ -22,7 +20,6 @@
"price_list_rate": 20,
"valid_from": "2017-04-18",
"valid_upto": "2017-04-26",
- "min_qty": 7,
"customer": "_Test Customer",
"uom": "_Test UOM"
},
@@ -31,19 +28,15 @@
"item_code": "_Test Item Home Desktop 100",
"price_list": "_Test Price List",
"price_list_rate": 1000,
- "min_qty" : 10,
"valid_from": "2017-04-10",
- "valid_upto": "2017-04-17",
- "min_qty": 2
+ "valid_upto": "2017-04-17"
},
{
"doctype": "Item Price",
"item_code": "_Test Item Home Desktop Manufactured",
"price_list": "_Test Price List",
"price_list_rate": 1000,
- "min_qty" : 10,
"valid_from": "2017-04-10",
- "valid_upto": "2017-04-17",
- "min_qty": 2
+ "valid_upto": "2017-04-17"
}
]
diff --git a/erpnext/stock/doctype/material_request_item/material_request_item.json b/erpnext/stock/doctype/material_request_item/material_request_item.json
index 795971b5e3d..9d1dafb136b 100644
--- a/erpnext/stock/doctype/material_request_item/material_request_item.json
+++ b/erpnext/stock/doctype/material_request_item/material_request_item.json
@@ -1,4 +1,5 @@
{
+ "actions": [],
"autoname": "hash",
"creation": "2013-02-22 01:28:02",
"doctype": "DocType",
@@ -185,12 +186,14 @@
{
"fieldname": "rate",
"fieldtype": "Currency",
- "label": "Rate"
+ "label": "Rate",
+ "no_copy": 1
},
{
"fieldname": "amount",
"fieldtype": "Currency",
"label": "Amount",
+ "no_copy": 1,
"read_only": 1
},
{
@@ -407,7 +410,8 @@
],
"idx": 1,
"istable": 1,
- "modified": "2019-06-02 06:49:36.493957",
+ "links": [],
+ "modified": "2020-02-25 03:09:10.698967",
"modified_by": "Administrator",
"module": "Stock",
"name": "Material Request Item",
diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
index aa09d3bfe5f..a51b25bf36d 100644
--- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -7,6 +7,7 @@ import frappe, erpnext
import frappe.defaults
from frappe.utils import cint, flt, cstr, today, random_string
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import make_purchase_invoice
+from erpnext.stock.doctype.item.test_item import create_item
from erpnext import set_perpetual_inventory
from erpnext.stock.doctype.serial_no.serial_no import SerialNoDuplicateError
from erpnext.accounts.doctype.account.test_account import get_inventory_account
@@ -50,6 +51,30 @@ class TestPurchaseReceipt(unittest.TestCase):
self.assertEqual(current_bin_stock_value, existing_bin_stock_value + 250)
self.assertFalse(get_gl_entries("Purchase Receipt", pr.name))
+
+ def test_batched_serial_no_purchase(self):
+ item = frappe.db.exists("Item", {'item_name': 'Batched Serialized Item'})
+ if not item:
+ item = create_item("Batched Serialized Item")
+ item.has_batch_no = 1
+ item.create_new_batch = 1
+ item.has_serial_no = 1
+ item.batch_number_series = "BS-BATCH-.##"
+ item.serial_no_series = "BS-.####"
+ item.save()
+ else:
+ item = frappe.get_doc("Item", {'item_name': 'Batched Serialized Item'})
+
+ pr = make_purchase_receipt(item_code=item.name, qty=5, rate=500)
+
+ self.assertTrue(frappe.db.get_value('Batch', {'item': item.name, 'reference_name': pr.name}))
+
+ pr.load_from_db()
+ batch_no = pr.items[0].batch_no
+ pr.cancel()
+
+ self.assertFalse(frappe.db.get_value('Batch', {'item': item.name, 'reference_name': pr.name}))
+ self.assertFalse(frappe.db.get_all('Serial No', {'batch_no': batch_no}))
def test_purchase_receipt_gl_entry(self):
pr = make_purchase_receipt(company="_Test Company with perpetual inventory", warehouse = "Stores - TCP1", supplier_warehouse = "Work in Progress - TCP1", get_multiple_items = True, get_taxes_and_charges = True)
@@ -279,6 +304,8 @@ class TestPurchaseReceipt(unittest.TestCase):
self.assertEqual(serial_no, frappe.db.get_value("Serial No",
{"purchase_document_type": "Purchase Receipt", "purchase_document_no": pr_doc.name}, "name"))
+ pr_doc.cancel()
+
item_code = "Test Auto Created Serial No"
if not frappe.db.exists("Item", item_code):
item = make_item(item_code, dict(has_serial_no=1, serial_no_series="KLJL.###"))
@@ -293,9 +320,9 @@ class TestPurchaseReceipt(unittest.TestCase):
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
- item_code = frappe.db.get_value('Item', {'has_serial_no': 1, 'is_fixed_asset': 0})
+ item_code = frappe.db.get_value('Item', {'has_serial_no': 1, 'is_fixed_asset': 0, "has_batch_no": 0})
if not item_code:
- item = make_item("Test Serial Item 1", dict(has_serial_no=1))
+ item = make_item("Test Serial Item 1", dict(has_serial_no=1, has_batch_no=0))
item_code = item.name
serial_no = random_string(5)
@@ -347,6 +374,33 @@ class TestPurchaseReceipt(unittest.TestCase):
location = frappe.db.get_value('Asset', assets[0].name, 'location')
self.assertEquals(location, "Test Location")
+
+ def test_purchase_return_with_submitted_asset(self):
+ from erpnext.stock.doctype.purchase_receipt.purchase_receipt import make_purchase_return
+
+ pr = make_purchase_receipt(item_code="Test Asset Item", qty=1)
+
+ asset = frappe.get_doc("Asset", {
+ 'purchase_receipt': pr.name
+ })
+ asset.available_for_use_date = frappe.utils.nowdate()
+ asset.gross_purchase_amount = 50.0
+ asset.append("finance_books", {
+ "expected_value_after_useful_life": 10,
+ "depreciation_method": "Straight Line",
+ "total_number_of_depreciations": 3,
+ "frequency_of_depreciation": 1,
+ "depreciation_start_date": frappe.utils.nowdate()
+ })
+ asset.submit()
+
+ pr_return = make_purchase_return(pr.name)
+ self.assertRaises(frappe.exceptions.ValidationError, pr_return.submit)
+
+ asset.load_from_db()
+ asset.cancel()
+
+ pr_return.submit()
def test_purchase_receipt_for_enable_allow_cost_center_in_entry_of_bs_account(self):
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
diff --git a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
index 16ec8db335c..d5cf4cadb14 100644
--- a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
+++ b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
@@ -222,7 +222,6 @@
"oldfieldname": "uom",
"oldfieldtype": "Link",
"options": "UOM",
- "print_hide": 1,
"print_width": "100px",
"reqd": 1,
"width": "100px"
@@ -823,7 +822,8 @@
],
"idx": 1,
"istable": 1,
- "modified": "2019-10-14 16:03:25.499557",
+ "links": [],
+ "modified": "2020-03-05 14:19:48.799370",
"modified_by": "Administrator",
"module": "Stock",
"name": "Purchase Receipt Item",
diff --git a/erpnext/stock/doctype/serial_no/serial_no.json b/erpnext/stock/doctype/serial_no/serial_no.json
index 712aadc5254..fb28b5c079d 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.json
+++ b/erpnext/stock/doctype/serial_no/serial_no.json
@@ -6,6 +6,7 @@
"description": "Distinct unit of an Item",
"doctype": "DocType",
"document_type": "Setup",
+ "engine": "InnoDB",
"field_order": [
"details",
"column_break0",
@@ -104,10 +105,11 @@
},
{
"fieldname": "batch_no",
- "fieldtype": "Data",
+ "fieldtype": "Link",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Batch No",
+ "options": "Batch",
"read_only": 1
},
{
@@ -425,7 +427,7 @@
],
"icon": "fa fa-barcode",
"idx": 1,
- "modified": "2019-08-07 17:28:32.243280",
+ "modified": "2020-02-28 19:31:09.357323",
"modified_by": "Administrator",
"module": "Stock",
"name": "Serial No",
diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py
index 50f27c18e31..31f84c9aaed 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.py
+++ b/erpnext/stock/doctype/serial_no/serial_no.py
@@ -205,6 +205,7 @@ def process_serial_no(sle):
def validate_serial_no(sle, item_det):
serial_nos = get_serial_nos(sle.serial_no) if sle.serial_no else []
+ validate_material_transfer_entry(sle)
if item_det.has_serial_no==0:
if serial_nos:
@@ -224,7 +225,9 @@ def validate_serial_no(sle, item_det):
for serial_no in serial_nos:
if frappe.db.exists("Serial No", serial_no):
- sr = frappe.get_doc("Serial No", serial_no)
+ sr = frappe.db.get_value("Serial No", serial_no, ["name", "item_code", "batch_no", "sales_order",
+ "delivery_document_no", "delivery_document_type", "warehouse",
+ "purchase_document_no", "company"], as_dict=1)
if sr.item_code!=sle.item_code:
if not allow_serial_nos_with_different_item(serial_no, sle):
@@ -305,6 +308,19 @@ def validate_serial_no(sle, item_det):
frappe.throw(_("Cannot cancel {0} {1} because Serial No {2} does not belong to the warehouse {3}")
.format(sle.voucher_type, sle.voucher_no, serial_no, sle.warehouse))
+def validate_material_transfer_entry(sle_doc):
+ sle_doc.update({
+ "skip_update_serial_no": False,
+ "skip_serial_no_validaiton": False
+ })
+
+ if (sle_doc.voucher_type == "Stock Entry" and sle_doc.is_cancelled == "No" and
+ frappe.get_cached_value("Stock Entry", sle_doc.voucher_no, "purpose") == "Material Transfer"):
+ if sle_doc.actual_qty < 0:
+ sle_doc.skip_update_serial_no = True
+ else:
+ sle_doc.skip_serial_no_validaiton = True
+
def validate_so_serial_no(sr, sales_order,):
if not sr.sales_order or sr.sales_order!= sales_order:
frappe.throw(_("""Sales Order {0} has reservation for item {1}, you can
@@ -312,7 +328,8 @@ def validate_so_serial_no(sr, sales_order,):
be delivered""").format(sales_order, sr.item_code, sr.name))
def has_duplicate_serial_no(sn, sle):
- if sn.warehouse and sle.voucher_type != 'Stock Reconciliation':
+ if (sn.warehouse and not sle.skip_serial_no_validaiton
+ and sle.voucher_type != 'Stock Reconciliation'):
return True
if sn.company != sle.company:
@@ -337,7 +354,7 @@ def allow_serial_nos_with_different_item(sle_serial_no, sle):
"""
allow_serial_nos = False
if sle.voucher_type=="Stock Entry" and cint(sle.actual_qty) > 0:
- stock_entry = frappe.get_doc("Stock Entry", sle.voucher_no)
+ stock_entry = frappe.get_cached_doc("Stock Entry", sle.voucher_no)
if stock_entry.purpose in ("Repack", "Manufacture"):
for d in stock_entry.get("items"):
if d.serial_no and (d.s_warehouse if sle.is_cancelled=="No" else d.t_warehouse):
@@ -348,6 +365,7 @@ def allow_serial_nos_with_different_item(sle_serial_no, sle):
return allow_serial_nos
def update_serial_nos(sle, item_det):
+ if sle.skip_update_serial_no: return
if sle.is_cancelled == "No" and not sle.serial_no and cint(sle.actual_qty) > 0 \
and item_det.has_serial_no == 1 and item_det.serial_no_series:
serial_nos = get_auto_serial_nos(item_det.serial_no_series, sle.actual_qty)
@@ -367,22 +385,16 @@ def auto_make_serial_nos(args):
serial_nos = get_serial_nos(args.get('serial_no'))
created_numbers = []
for serial_no in serial_nos:
+ is_new = False
if frappe.db.exists("Serial No", serial_no):
- sr = frappe.get_doc("Serial No", serial_no)
- sr.via_stock_ledger = True
- sr.item_code = args.get('item_code')
- sr.warehouse = args.get('warehouse') if args.get('actual_qty', 0) > 0 else None
- sr.batch_no = args.get('batch_no')
- sr.location = args.get('location')
- sr.company = args.get('company')
- sr.supplier = args.get('supplier')
- if sr.sales_order and args.get('voucher_type') == "Stock Entry" \
- and not args.get('actual_qty', 0) > 0:
- sr.sales_order = None
- sr.update_serial_no_reference()
- sr.save(ignore_permissions=True)
+ sr = frappe.get_cached_doc("Serial No", serial_no)
elif args.get('actual_qty', 0) > 0:
- created_numbers.append(make_serial_no(serial_no, args))
+ sr = frappe.new_doc("Serial No")
+ is_new = True
+
+ sr = update_args_for_serial_no(sr, serial_no, args, is_new=is_new)
+ if is_new:
+ created_numbers.append(sr.name)
form_links = list(map(lambda d: frappe.utils.get_link_to_form('Serial No', d), created_numbers))
if len(form_links) == 1:
@@ -399,20 +411,34 @@ def get_serial_nos(serial_no):
return [s.strip() for s in cstr(serial_no).strip().upper().replace(',', '\n').split('\n')
if s.strip()]
-def make_serial_no(serial_no, args):
- sr = frappe.new_doc("Serial No")
- sr.serial_no = serial_no
- sr.item_code = args.get('item_code')
- sr.company = args.get('company')
- sr.batch_no = args.get('batch_no')
- sr.via_stock_ledger = args.get('via_stock_ledger') or True
- sr.warehouse = args.get('warehouse')
+def update_args_for_serial_no(serial_no_doc, serial_no, args, is_new=False):
+ serial_no_doc.update({
+ "item_code": args.get("item_code"),
+ "company": args.get("company"),
+ "batch_no": args.get("batch_no"),
+ "via_stock_ledger": args.get("via_stock_ledger") or True,
+ "supplier": args.get("supplier"),
+ "location": args.get("location"),
+ "warehouse": (args.get("warehouse")
+ if args.get("actual_qty", 0) > 0 else None)
+ })
- sr.validate_item()
- sr.update_serial_no_reference(serial_no)
- sr.db_insert()
+ if is_new:
+ serial_no_doc.serial_no = serial_no
- return sr.name
+ if (serial_no_doc.sales_order and args.get("voucher_type") == "Stock Entry"
+ and not args.get("actual_qty", 0) > 0):
+ serial_no_doc.sales_order = None
+
+ serial_no_doc.validate_item()
+ serial_no_doc.update_serial_no_reference(serial_no)
+
+ if is_new:
+ serial_no_doc.db_insert()
+ else:
+ serial_no_doc.db_update()
+
+ return serial_no_doc
def update_serial_nos_after_submit(controller, parentfield):
stock_ledger_entries = frappe.db.sql("""select voucher_detail_no, serial_no, actual_qty, warehouse
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index 6220b1e9135..e01a7ca9727 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -878,10 +878,8 @@ erpnext.stock.select_batch_and_serial_no = (frm, item) => {
}
}
- if(item && item.has_serial_no
- && frm.doc.purpose === 'Material Receipt') {
- return;
- }
+ if(item && !item.has_serial_no && item.has_batch_no) return;
+ if (frm.doc.purpose === 'Material Receipt') return;
frappe.require("assets/erpnext/js/utils/serial_no_batch_selector.js", function() {
new erpnext.SerialNoBatchSelector({
diff --git a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.json b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.json
index c9eba71b0d0..c03eb79eeca 100644
--- a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.json
+++ b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.json
@@ -240,6 +240,7 @@
"options": "Company",
"print_width": "150px",
"read_only": 1,
+ "search_index": 1,
"width": "150px"
},
{
@@ -274,7 +275,7 @@
"icon": "fa fa-list",
"idx": 1,
"in_create": 1,
- "modified": "2019-11-27 12:17:31.522675",
+ "modified": "2020-02-25 22:53:33.504681",
"modified_by": "Administrator",
"module": "Stock",
"name": "Stock Ledger Entry",
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
index ca2741ccfba..afa239466b5 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
@@ -190,6 +190,9 @@ class StockReconciliation(StockController):
has_serial_no = True
self.get_sle_for_serialized_items(row, sl_entries)
else:
+ if row.serial_no or row.batch_no:
+ frappe.throw(_("Row #{0}: Item {1} is not a Serialized/Batched Item. It cannot have a Serial No/Batch No against it.") \
+ .format(row.idx, frappe.bold(row.item_code)))
previous_sle = get_previous_sle({
"item_code": row.item_code,
"warehouse": row.warehouse,
diff --git a/erpnext/stock/reorder_item.py b/erpnext/stock/reorder_item.py
index 39fb0240236..97776739a87 100644
--- a/erpnext/stock/reorder_item.py
+++ b/erpnext/stock/reorder_item.py
@@ -116,6 +116,8 @@ def create_material_request(material_requests):
else:
exceptions_list.append(frappe.get_traceback())
+ frappe.log_error(frappe.get_traceback())
+
for request_type in material_requests:
for company in material_requests[request_type]:
try:
@@ -158,6 +160,7 @@ def create_material_request(material_requests):
schedule_dates = [d.schedule_date for d in mr.items]
mr.schedule_date = max(schedule_dates or [nowdate()])
+ mr.flags.ignore_mandatory = True
mr.insert()
mr.submit()
mr_list.append(mr)
diff --git a/erpnext/stock/utils.py b/erpnext/stock/utils.py
index 2c6c95393bc..f3381c76091 100644
--- a/erpnext/stock/utils.py
+++ b/erpnext/stock/utils.py
@@ -136,7 +136,7 @@ def get_bin(item_code, warehouse):
bin_obj.flags.ignore_permissions = 1
bin_obj.insert()
else:
- bin_obj = frappe.get_doc('Bin', bin)
+ bin_obj = frappe.get_cached_doc('Bin', bin)
bin_obj.flags.ignore_permissions = True
return bin_obj
diff --git a/erpnext/support/doctype/issue/issue.json b/erpnext/support/doctype/issue/issue.json
index 222554bda13..51b49e8049b 100644
--- a/erpnext/support/doctype/issue/issue.json
+++ b/erpnext/support/doctype/issue/issue.json
@@ -363,8 +363,9 @@
],
"icon": "fa fa-ticket",
"idx": 7,
- "modified": "2019-09-11 09:03:57.465623",
- "modified_by": "himanshu@erpnext.com",
+ "links": [],
+ "modified": "2020-02-26 02:19:49.477928",
+ "modified_by": "Administrator",
"module": "Support",
"name": "Issue",
"owner": "Administrator",
@@ -384,9 +385,9 @@
"quick_entry": 1,
"search_fields": "status,customer,subject,raised_by",
"sort_field": "modified",
- "sort_order": "ASC",
+ "sort_order": "DESC",
"timeline_field": "customer",
"title_field": "subject",
"track_changes": 1,
"track_seen": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/templates/includes/projects/project_row.html b/erpnext/templates/includes/projects/project_row.html
index 55b02e20045..73c83ef560b 100644
--- a/erpnext/templates/includes/projects/project_row.html
+++ b/erpnext/templates/includes/projects/project_row.html
@@ -1,6 +1,6 @@
{% if doc.status=="Open" %}
-
+
diff --git a/package.json b/package.json
index 0e09cebf56e..9701bf3a21e 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,14 @@
{
- "dependencies": {
- "cypress": "^3.1.4"
+ "name": "erpnext",
+ "description": "Open Source ERP System powered by the Frappe Framework",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/frappe/erpnext.git"
+ },
+ "homepage": "https://erpnext.com",
+ "author": "Frappe Technologies Pvt. Ltd.",
+ "license": "GPL-3.0",
+ "bugs": {
+ "url": "https://github.com/frappe/erpnext/issues"
}
}
diff --git a/yarn.lock b/yarn.lock
index 6f1ff10839c..fb57ccd13af 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,1305 +2,3 @@
# yarn lockfile v1
-"@cypress/listr-verbose-renderer@0.4.1":
- version "0.4.1"
- resolved "https://registry.yarnpkg.com/@cypress/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#a77492f4b11dcc7c446a34b3e28721afd33c642a"
- integrity sha1-p3SS9LEdzHxEajSz4ochr9M8ZCo=
- dependencies:
- chalk "^1.1.3"
- cli-cursor "^1.0.2"
- date-fns "^1.27.2"
- figures "^1.7.0"
-
-"@cypress/xvfb@1.2.3":
- version "1.2.3"
- resolved "https://registry.yarnpkg.com/@cypress/xvfb/-/xvfb-1.2.3.tgz#6319afdcdcff7d1505daeeaa84484d0596189860"
- integrity sha512-yYrK+/bgL3hwoRHMZG4r5fyLniCy1pXex5fimtewAY6vE/jsVs8Q37UsEO03tFlcmiLnQ3rBNMaZBYTi/+C1cw==
- dependencies:
- debug "^3.1.0"
- lodash.once "^4.1.1"
-
-"@types/blob-util@1.3.3":
- version "1.3.3"
- resolved "https://registry.yarnpkg.com/@types/blob-util/-/blob-util-1.3.3.tgz#adba644ae34f88e1dd9a5864c66ad651caaf628a"
- integrity sha512-4ahcL/QDnpjWA2Qs16ZMQif7HjGP2cw3AGjHabybjw7Vm1EKu+cfQN1D78BaZbS1WJNa1opSMF5HNMztx7lR0w==
-
-"@types/bluebird@3.5.18":
- version "3.5.18"
- resolved "https://registry.yarnpkg.com/@types/bluebird/-/bluebird-3.5.18.tgz#6a60435d4663e290f3709898a4f75014f279c4d6"
- integrity sha512-OTPWHmsyW18BhrnG5x8F7PzeZ2nFxmHGb42bZn79P9hl+GI5cMzyPgQTwNjbem0lJhoru/8vtjAFCUOu3+gE2w==
-
-"@types/chai-jquery@1.1.35":
- version "1.1.35"
- resolved "https://registry.yarnpkg.com/@types/chai-jquery/-/chai-jquery-1.1.35.tgz#9a8f0a39ec0851b2768a8f8c764158c2a2568d04"
- integrity sha512-7aIt9QMRdxuagLLI48dPz96YJdhu64p6FCa6n4qkGN5DQLHnrIjZpD9bXCvV2G0NwgZ1FAmfP214dxc5zNCfgQ==
- dependencies:
- "@types/chai" "*"
- "@types/jquery" "*"
-
-"@types/chai@*":
- version "4.1.7"
- resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.1.7.tgz#1b8e33b61a8c09cbe1f85133071baa0dbf9fa71a"
- integrity sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA==
-
-"@types/chai@4.0.8":
- version "4.0.8"
- resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.0.8.tgz#d27600e9ba2f371e08695d90a0fe0408d89c7be7"
- integrity sha512-m812CONwdZn/dMzkIJEY0yAs4apyTkTORgfB2UsMOxgkUbC205AHnm4T8I0I5gPg9MHrFc1dJ35iS75c0CJkjg==
-
-"@types/jquery@*":
- version "3.3.29"
- resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.3.29.tgz#680a2219ce3c9250483722fccf5570d1e2d08abd"
- integrity sha512-FhJvBninYD36v3k6c+bVk1DSZwh7B5Dpb/Pyk3HKVsiohn0nhbefZZ+3JXbWQhFyt0MxSl2jRDdGQPHeOHFXrQ==
- dependencies:
- "@types/sizzle" "*"
-
-"@types/jquery@3.3.6":
- version "3.3.6"
- resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.3.6.tgz#5932ead926307ca21e5b36808257f7c926b06565"
- integrity sha512-403D4wN95Mtzt2EoQHARf5oe/jEPhzBOBNrunk+ydQGW8WmkQ/E8rViRAEB1qEt/vssfGfNVD6ujP4FVeegrLg==
-
-"@types/lodash@4.14.87":
- version "4.14.87"
- resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.87.tgz#55f92183b048c2c64402afe472f8333f4e319a6b"
- integrity sha512-AqRC+aEF4N0LuNHtcjKtvF9OTfqZI0iaBoe3dA6m/W+/YZJBZjBmW/QIZ8fBeXC6cnytSY9tBoFBqZ9uSCeVsw==
-
-"@types/minimatch@3.0.3":
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
- integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
-
-"@types/mocha@2.2.44":
- version "2.2.44"
- resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.44.tgz#1d4a798e53f35212fd5ad4d04050620171cd5b5e"
- integrity sha512-k2tWTQU8G4+iSMvqKi0Q9IIsWAp/n8xzdZS4Q4YVIltApoMA00wFBFdlJnmoaK1/z7B0Cy0yPe6GgXteSmdUNw==
-
-"@types/sinon-chai@2.7.29":
- version "2.7.29"
- resolved "https://registry.yarnpkg.com/@types/sinon-chai/-/sinon-chai-2.7.29.tgz#4db01497e2dd1908b2bd30d1782f456353f5f723"
- integrity sha512-EkI/ZvJT4hglWo7Ipf9SX+J+R9htNOMjW8xiOhce7+0csqvgoF5IXqY5Ae1GqRgNtWCuaywR5HjVa1snkTqpOw==
- dependencies:
- "@types/chai" "*"
- "@types/sinon" "*"
-
-"@types/sinon@*":
- version "7.0.2"
- resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-7.0.2.tgz#234c03dd39bfa97616b28215caea3de043c63310"
- integrity sha512-YvJOqPk4kh1eQyxuASDD4MDK27XWAhtw6hJ7rRayEOkkTpZkqDWpDb4OjLVzFGdapOuUgZdnqO+71Q3utCJtcA==
-
-"@types/sinon@7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-7.0.0.tgz#84e707e157ec17d3e4c2a137f41fc3f416c0551e"
- integrity sha512-kcYoPw0uKioFVC/oOqafk2yizSceIQXCYnkYts9vJIwQklFRsMubTObTDrjQamUyBRd47332s85074cd/hCwxg==
-
-"@types/sizzle@*":
- version "2.3.2"
- resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.2.tgz#a811b8c18e2babab7d542b3365887ae2e4d9de47"
- integrity sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==
-
-ajv@^5.1.0:
- version "5.5.2"
- resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965"
- integrity sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=
- dependencies:
- co "^4.6.0"
- fast-deep-equal "^1.0.0"
- fast-json-stable-stringify "^2.0.0"
- json-schema-traverse "^0.3.0"
-
-ansi-escapes@^1.0.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e"
- integrity sha1-06ioOzGapneTZisT52HHkRQiMG4=
-
-ansi-regex@^2.0.0:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
- integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8=
-
-ansi-styles@^2.2.1:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
- integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=
-
-ansi-styles@^3.2.1:
- version "3.2.1"
- resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
- integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
- dependencies:
- color-convert "^1.9.0"
-
-asn1@~0.2.3:
- version "0.2.4"
- resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
- integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==
- dependencies:
- safer-buffer "~2.1.0"
-
-assert-plus@1.0.0, assert-plus@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
- integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
-
-async@2.4.0:
- version "2.4.0"
- resolved "https://registry.yarnpkg.com/async/-/async-2.4.0.tgz#4990200f18ea5b837c2cc4f8c031a6985c385611"
- integrity sha1-SZAgDxjqW4N8LMT4wDGmmFw4VhE=
- dependencies:
- lodash "^4.14.0"
-
-asynckit@^0.4.0:
- version "0.4.0"
- resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
- integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
-
-aws-sign2@~0.7.0:
- version "0.7.0"
- resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
- integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
-
-aws4@^1.6.0:
- version "1.8.0"
- resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
- integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
-
-babel-runtime@^6.18.0:
- version "6.26.0"
- resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
- integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4=
- dependencies:
- core-js "^2.4.0"
- regenerator-runtime "^0.11.0"
-
-balanced-match@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
- integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
-
-bcrypt-pbkdf@^1.0.0:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
- integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
- dependencies:
- tweetnacl "^0.14.3"
-
-bluebird@3.5.0:
- version "3.5.0"
- resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.0.tgz#791420d7f551eea2897453a8a77653f96606d67c"
- integrity sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=
-
-brace-expansion@^1.1.7:
- version "1.1.11"
- resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
- integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
- dependencies:
- balanced-match "^1.0.0"
- concat-map "0.0.1"
-
-buffer-crc32@~0.2.3:
- version "0.2.13"
- resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
- integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=
-
-cachedir@1.3.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-1.3.0.tgz#5e01928bf2d95b5edd94b0942188246740e0dbc4"
- integrity sha512-O1ji32oyON9laVPJL1IZ5bmwd2cB46VfpxkDequezH+15FDzzVddEyrGEeX4WusDSqKxdyFdDQDEG1yo1GoWkg==
- dependencies:
- os-homedir "^1.0.1"
-
-caseless@~0.12.0:
- version "0.12.0"
- resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
- integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
-
-chalk@2.4.1, chalk@^2.0.1:
- version "2.4.1"
- resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
- integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==
- dependencies:
- ansi-styles "^3.2.1"
- escape-string-regexp "^1.0.5"
- supports-color "^5.3.0"
-
-chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
- integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=
- dependencies:
- ansi-styles "^2.2.1"
- escape-string-regexp "^1.0.2"
- has-ansi "^2.0.0"
- strip-ansi "^3.0.0"
- supports-color "^2.0.0"
-
-check-more-types@2.24.0:
- version "2.24.0"
- resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600"
- integrity sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA=
-
-ci-info@^1.0.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497"
- integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==
-
-cli-cursor@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987"
- integrity sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=
- dependencies:
- restore-cursor "^1.0.1"
-
-cli-spinners@^0.1.2:
- version "0.1.2"
- resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c"
- integrity sha1-u3ZNiOGF+54eaiofGXcjGPYF4xw=
-
-cli-truncate@^0.2.1:
- version "0.2.1"
- resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574"
- integrity sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=
- dependencies:
- slice-ansi "0.0.4"
- string-width "^1.0.1"
-
-co@^4.6.0:
- version "4.6.0"
- resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
- integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=
-
-code-point-at@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
- integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
-
-color-convert@^1.9.0:
- version "1.9.3"
- resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
- integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
- dependencies:
- color-name "1.1.3"
-
-color-name@1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
- integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
-
-combined-stream@^1.0.6, combined-stream@~1.0.5:
- version "1.0.7"
- resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828"
- integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==
- dependencies:
- delayed-stream "~1.0.0"
-
-commander@2.11.0:
- version "2.11.0"
- resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563"
- integrity sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==
-
-common-tags@1.4.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.4.0.tgz#1187be4f3d4cf0c0427d43f74eef1f73501614c0"
- integrity sha1-EYe+Tz1M8MBCfUP3Tu8fc1AWFMA=
- dependencies:
- babel-runtime "^6.18.0"
-
-concat-map@0.0.1:
- version "0.0.1"
- resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
- integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
-
-concat-stream@1.6.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7"
- integrity sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=
- dependencies:
- inherits "^2.0.3"
- readable-stream "^2.2.2"
- typedarray "^0.0.6"
-
-core-js@^2.4.0:
- version "2.6.1"
- resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.1.tgz#87416ae817de957a3f249b3b5ca475d4aaed6042"
- integrity sha512-L72mmmEayPJBejKIWe2pYtGis5r0tQ5NaJekdhyXgeMQTpJoBsH0NL4ElY2LfSoV15xeQWKQ+XTTOZdyero5Xg==
-
-core-util-is@1.0.2, core-util-is@~1.0.0:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
- integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
-
-cross-spawn@^6.0.0:
- version "6.0.5"
- resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
- integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
- dependencies:
- nice-try "^1.0.4"
- path-key "^2.0.1"
- semver "^5.5.0"
- shebang-command "^1.2.0"
- which "^1.2.9"
-
-cypress@^3.1.4:
- version "3.1.4"
- resolved "https://registry.yarnpkg.com/cypress/-/cypress-3.1.4.tgz#2af04da05e09f9d3871d05713b364472744c4216"
- integrity sha512-8VJYtCAFqHXMnRDo4vdomR2CqfmhtReoplmbkXVspeKhKxU8WsZl0Nh5yeil8txxhq+YQwDrInItUqIm35Vw+g==
- dependencies:
- "@cypress/listr-verbose-renderer" "0.4.1"
- "@cypress/xvfb" "1.2.3"
- "@types/blob-util" "1.3.3"
- "@types/bluebird" "3.5.18"
- "@types/chai" "4.0.8"
- "@types/chai-jquery" "1.1.35"
- "@types/jquery" "3.3.6"
- "@types/lodash" "4.14.87"
- "@types/minimatch" "3.0.3"
- "@types/mocha" "2.2.44"
- "@types/sinon" "7.0.0"
- "@types/sinon-chai" "2.7.29"
- bluebird "3.5.0"
- cachedir "1.3.0"
- chalk "2.4.1"
- check-more-types "2.24.0"
- commander "2.11.0"
- common-tags "1.4.0"
- debug "3.1.0"
- execa "0.10.0"
- executable "4.1.1"
- extract-zip "1.6.6"
- fs-extra "4.0.1"
- getos "3.1.0"
- glob "7.1.2"
- is-ci "1.0.10"
- is-installed-globally "0.1.0"
- lazy-ass "1.6.0"
- listr "0.12.0"
- lodash "4.17.11"
- log-symbols "2.2.0"
- minimist "1.2.0"
- moment "2.22.2"
- ramda "0.24.1"
- request "2.87.0"
- request-progress "0.3.1"
- supports-color "5.1.0"
- tmp "0.0.31"
- url "0.11.0"
- yauzl "2.8.0"
-
-dashdash@^1.12.0:
- version "1.14.1"
- resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
- integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=
- dependencies:
- assert-plus "^1.0.0"
-
-date-fns@^1.27.2:
- version "1.30.1"
- resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c"
- integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==
-
-debug@2.6.9:
- version "2.6.9"
- resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
- integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
- dependencies:
- ms "2.0.0"
-
-debug@3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
- integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
- dependencies:
- ms "2.0.0"
-
-debug@^3.1.0:
- version "3.2.6"
- resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
- integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
- dependencies:
- ms "^2.1.1"
-
-delayed-stream@~1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
- integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
-
-ecc-jsbn@~0.1.1:
- version "0.1.2"
- resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
- integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=
- dependencies:
- jsbn "~0.1.0"
- safer-buffer "^2.1.0"
-
-elegant-spinner@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e"
- integrity sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=
-
-escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
- integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
-
-execa@0.10.0:
- version "0.10.0"
- resolved "https://registry.yarnpkg.com/execa/-/execa-0.10.0.tgz#ff456a8f53f90f8eccc71a96d11bdfc7f082cb50"
- integrity sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==
- dependencies:
- cross-spawn "^6.0.0"
- get-stream "^3.0.0"
- is-stream "^1.1.0"
- npm-run-path "^2.0.0"
- p-finally "^1.0.0"
- signal-exit "^3.0.0"
- strip-eof "^1.0.0"
-
-executable@4.1.1:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/executable/-/executable-4.1.1.tgz#41532bff361d3e57af4d763b70582db18f5d133c"
- integrity sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==
- dependencies:
- pify "^2.2.0"
-
-exit-hook@^1.0.0:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8"
- integrity sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=
-
-extend@~3.0.1:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
- integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
-
-extract-zip@1.6.6:
- version "1.6.6"
- resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.6.tgz#1290ede8d20d0872b429fd3f351ca128ec5ef85c"
- integrity sha1-EpDt6NINCHK0Kf0/NRyhKOxe+Fw=
- dependencies:
- concat-stream "1.6.0"
- debug "2.6.9"
- mkdirp "0.5.0"
- yauzl "2.4.1"
-
-extsprintf@1.3.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
- integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=
-
-extsprintf@^1.2.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
- integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
-
-fast-deep-equal@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614"
- integrity sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=
-
-fast-json-stable-stringify@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
- integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I=
-
-fd-slicer@~1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65"
- integrity sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=
- dependencies:
- pend "~1.2.0"
-
-figures@^1.7.0:
- version "1.7.0"
- resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e"
- integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=
- dependencies:
- escape-string-regexp "^1.0.5"
- object-assign "^4.1.0"
-
-forever-agent@~0.6.1:
- version "0.6.1"
- resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
- integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
-
-form-data@~2.3.1:
- version "2.3.3"
- resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
- integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==
- dependencies:
- asynckit "^0.4.0"
- combined-stream "^1.0.6"
- mime-types "^2.1.12"
-
-fs-extra@4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.1.tgz#7fc0c6c8957f983f57f306a24e5b9ddd8d0dd880"
- integrity sha1-f8DGyJV/mD9X8waiTlud3Y0N2IA=
- dependencies:
- graceful-fs "^4.1.2"
- jsonfile "^3.0.0"
- universalify "^0.1.0"
-
-fs.realpath@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
- integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
-
-get-stream@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
- integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=
-
-getos@3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/getos/-/getos-3.1.0.tgz#db3aa4df15a3295557ce5e81aa9e3e5cdfaa6567"
- integrity sha512-i9vrxtDu5DlLVFcrbqUqGWYlZN/zZ4pGMICCAcZoYsX3JA54nYp8r5EThw5K+m2q3wszkx4Th746JstspB0H4Q==
- dependencies:
- async "2.4.0"
-
-getpass@^0.1.1:
- version "0.1.7"
- resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
- integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=
- dependencies:
- assert-plus "^1.0.0"
-
-glob@7.1.2:
- version "7.1.2"
- resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
- integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==
- dependencies:
- fs.realpath "^1.0.0"
- inflight "^1.0.4"
- inherits "2"
- minimatch "^3.0.4"
- once "^1.3.0"
- path-is-absolute "^1.0.0"
-
-global-dirs@^0.1.0:
- version "0.1.1"
- resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445"
- integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=
- dependencies:
- ini "^1.3.4"
-
-graceful-fs@^4.1.2, graceful-fs@^4.1.6:
- version "4.1.15"
- resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
- integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==
-
-har-schema@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
- integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
-
-har-validator@~5.0.3:
- version "5.0.3"
- resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd"
- integrity sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=
- dependencies:
- ajv "^5.1.0"
- har-schema "^2.0.0"
-
-has-ansi@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
- integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=
- dependencies:
- ansi-regex "^2.0.0"
-
-has-flag@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51"
- integrity sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=
-
-has-flag@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
- integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
-
-http-signature@~1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
- integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
- dependencies:
- assert-plus "^1.0.0"
- jsprim "^1.2.2"
- sshpk "^1.7.0"
-
-indent-string@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80"
- integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=
- dependencies:
- repeating "^2.0.0"
-
-indent-string@^3.0.0:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289"
- integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=
-
-inflight@^1.0.4:
- version "1.0.6"
- resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
- integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
- dependencies:
- once "^1.3.0"
- wrappy "1"
-
-inherits@2, inherits@^2.0.3, inherits@~2.0.3:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
- integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
-
-ini@^1.3.4:
- version "1.3.5"
- resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
- integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==
-
-is-ci@1.0.10:
- version "1.0.10"
- resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.0.10.tgz#f739336b2632365061a9d48270cd56ae3369318e"
- integrity sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=
- dependencies:
- ci-info "^1.0.0"
-
-is-finite@^1.0.0:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa"
- integrity sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=
- dependencies:
- number-is-nan "^1.0.0"
-
-is-fullwidth-code-point@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
- integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs=
- dependencies:
- number-is-nan "^1.0.0"
-
-is-installed-globally@0.1.0:
- version "0.1.0"
- resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80"
- integrity sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=
- dependencies:
- global-dirs "^0.1.0"
- is-path-inside "^1.0.0"
-
-is-path-inside@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036"
- integrity sha1-jvW33lBDej/cprToZe96pVy0gDY=
- dependencies:
- path-is-inside "^1.0.1"
-
-is-promise@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa"
- integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=
-
-is-stream@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
- integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
-
-is-typedarray@~1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
- integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
-
-isarray@~1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
- integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
-
-isexe@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
- integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
-
-isstream@~0.1.2:
- version "0.1.2"
- resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
- integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
-
-jsbn@~0.1.0:
- version "0.1.1"
- resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
- integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
-
-json-schema-traverse@^0.3.0:
- version "0.3.1"
- resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340"
- integrity sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=
-
-json-schema@0.2.3:
- version "0.2.3"
- resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
- integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
-
-json-stringify-safe@~5.0.1:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
- integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
-
-jsonfile@^3.0.0:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-3.0.1.tgz#a5ecc6f65f53f662c4415c7675a0331d0992ec66"
- integrity sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=
- optionalDependencies:
- graceful-fs "^4.1.6"
-
-jsprim@^1.2.2:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
- integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=
- dependencies:
- assert-plus "1.0.0"
- extsprintf "1.3.0"
- json-schema "0.2.3"
- verror "1.10.0"
-
-lazy-ass@1.6.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/lazy-ass/-/lazy-ass-1.6.0.tgz#7999655e8646c17f089fdd187d150d3324d54513"
- integrity sha1-eZllXoZGwX8In90YfRUNMyTVRRM=
-
-listr-silent-renderer@^1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e"
- integrity sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=
-
-listr-update-renderer@^0.2.0:
- version "0.2.0"
- resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.2.0.tgz#ca80e1779b4e70266807e8eed1ad6abe398550f9"
- integrity sha1-yoDhd5tOcCZoB+ju0a1qvjmFUPk=
- dependencies:
- chalk "^1.1.3"
- cli-truncate "^0.2.1"
- elegant-spinner "^1.0.1"
- figures "^1.7.0"
- indent-string "^3.0.0"
- log-symbols "^1.0.2"
- log-update "^1.0.2"
- strip-ansi "^3.0.1"
-
-listr-verbose-renderer@^0.4.0:
- version "0.4.1"
- resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#8206f4cf6d52ddc5827e5fd14989e0e965933a35"
- integrity sha1-ggb0z21S3cWCfl/RSYng6WWTOjU=
- dependencies:
- chalk "^1.1.3"
- cli-cursor "^1.0.2"
- date-fns "^1.27.2"
- figures "^1.7.0"
-
-listr@0.12.0:
- version "0.12.0"
- resolved "https://registry.yarnpkg.com/listr/-/listr-0.12.0.tgz#6bce2c0f5603fa49580ea17cd6a00cc0e5fa451a"
- integrity sha1-a84sD1YD+klYDqF81qAMwOX6RRo=
- dependencies:
- chalk "^1.1.3"
- cli-truncate "^0.2.1"
- figures "^1.7.0"
- indent-string "^2.1.0"
- is-promise "^2.1.0"
- is-stream "^1.1.0"
- listr-silent-renderer "^1.1.1"
- listr-update-renderer "^0.2.0"
- listr-verbose-renderer "^0.4.0"
- log-symbols "^1.0.2"
- log-update "^1.0.2"
- ora "^0.2.3"
- p-map "^1.1.1"
- rxjs "^5.0.0-beta.11"
- stream-to-observable "^0.1.0"
- strip-ansi "^3.0.1"
-
-lodash.once@^4.1.1:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
- integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=
-
-lodash@4.17.11, lodash@^4.14.0:
- version "4.17.11"
- resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
- integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==
-
-log-symbols@2.2.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a"
- integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==
- dependencies:
- chalk "^2.0.1"
-
-log-symbols@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18"
- integrity sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=
- dependencies:
- chalk "^1.0.0"
-
-log-update@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/log-update/-/log-update-1.0.2.tgz#19929f64c4093d2d2e7075a1dad8af59c296b8d1"
- integrity sha1-GZKfZMQJPS0ucHWh2tivWcKWuNE=
- dependencies:
- ansi-escapes "^1.0.0"
- cli-cursor "^1.0.2"
-
-mime-db@~1.37.0:
- version "1.37.0"
- resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8"
- integrity sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==
-
-mime-types@^2.1.12, mime-types@~2.1.17:
- version "2.1.21"
- resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96"
- integrity sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==
- dependencies:
- mime-db "~1.37.0"
-
-minimatch@^3.0.4:
- version "3.0.4"
- resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
- integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
- dependencies:
- brace-expansion "^1.1.7"
-
-minimist@0.0.8:
- version "0.0.8"
- resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
- integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
-
-minimist@1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
- integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=
-
-mkdirp@0.5.0:
- version "0.5.0"
- resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.0.tgz#1d73076a6df986cd9344e15e71fcc05a4c9abf12"
- integrity sha1-HXMHam35hs2TROFecfzAWkyavxI=
- dependencies:
- minimist "0.0.8"
-
-moment@2.22.2:
- version "2.22.2"
- resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66"
- integrity sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=
-
-ms@2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
- integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
-
-ms@^2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
- integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
-
-nice-try@^1.0.4:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
- integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
-
-npm-run-path@^2.0.0:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
- integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=
- dependencies:
- path-key "^2.0.0"
-
-number-is-nan@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
- integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
-
-oauth-sign@~0.8.2:
- version "0.8.2"
- resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
- integrity sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=
-
-object-assign@^4.0.1, object-assign@^4.1.0:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
- integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
-
-once@^1.3.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
- integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
- dependencies:
- wrappy "1"
-
-onetime@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789"
- integrity sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=
-
-ora@^0.2.3:
- version "0.2.3"
- resolved "https://registry.yarnpkg.com/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4"
- integrity sha1-N1J9Igrc1Tw5tzVx11QVbV22V6Q=
- dependencies:
- chalk "^1.1.1"
- cli-cursor "^1.0.2"
- cli-spinners "^0.1.2"
- object-assign "^4.0.1"
-
-os-homedir@^1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
- integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M=
-
-os-tmpdir@~1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
- integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
-
-p-finally@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
- integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=
-
-p-map@^1.1.1:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b"
- integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==
-
-path-is-absolute@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
- integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
-
-path-is-inside@^1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
- integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=
-
-path-key@^2.0.0, path-key@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
- integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
-
-pend@~1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
- integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA=
-
-performance-now@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
- integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
-
-pify@^2.2.0:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
- integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw=
-
-process-nextick-args@~2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa"
- integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==
-
-punycode@1.3.2:
- version "1.3.2"
- resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
- integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=
-
-punycode@^1.4.1:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
- integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
-
-qs@~6.5.1:
- version "6.5.2"
- resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
- integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
-
-querystring@0.2.0:
- version "0.2.0"
- resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
- integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=
-
-ramda@0.24.1:
- version "0.24.1"
- resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.24.1.tgz#c3b7755197f35b8dc3502228262c4c91ddb6b857"
- integrity sha1-w7d1UZfzW43DUCIoJixMkd22uFc=
-
-readable-stream@^2.2.2:
- version "2.3.6"
- resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
- integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==
- dependencies:
- core-util-is "~1.0.0"
- inherits "~2.0.3"
- isarray "~1.0.0"
- process-nextick-args "~2.0.0"
- safe-buffer "~5.1.1"
- string_decoder "~1.1.1"
- util-deprecate "~1.0.1"
-
-regenerator-runtime@^0.11.0:
- version "0.11.1"
- resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
- integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
-
-repeating@^2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda"
- integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=
- dependencies:
- is-finite "^1.0.0"
-
-request-progress@0.3.1:
- version "0.3.1"
- resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-0.3.1.tgz#0721c105d8a96ac6b2ce8b2c89ae2d5ecfcf6b3a"
- integrity sha1-ByHBBdipasayzossia4tXs/Pazo=
- dependencies:
- throttleit "~0.0.2"
-
-request@2.87.0:
- version "2.87.0"
- resolved "https://registry.yarnpkg.com/request/-/request-2.87.0.tgz#32f00235cd08d482b4d0d68db93a829c0ed5756e"
- integrity sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==
- dependencies:
- aws-sign2 "~0.7.0"
- aws4 "^1.6.0"
- caseless "~0.12.0"
- combined-stream "~1.0.5"
- extend "~3.0.1"
- forever-agent "~0.6.1"
- form-data "~2.3.1"
- har-validator "~5.0.3"
- http-signature "~1.2.0"
- is-typedarray "~1.0.0"
- isstream "~0.1.2"
- json-stringify-safe "~5.0.1"
- mime-types "~2.1.17"
- oauth-sign "~0.8.2"
- performance-now "^2.1.0"
- qs "~6.5.1"
- safe-buffer "^5.1.1"
- tough-cookie "~2.3.3"
- tunnel-agent "^0.6.0"
- uuid "^3.1.0"
-
-restore-cursor@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541"
- integrity sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=
- dependencies:
- exit-hook "^1.0.0"
- onetime "^1.0.0"
-
-rxjs@^5.0.0-beta.11:
- version "5.5.12"
- resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.12.tgz#6fa61b8a77c3d793dbaf270bee2f43f652d741cc"
- integrity sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==
- dependencies:
- symbol-observable "1.0.1"
-
-safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
- version "5.1.2"
- resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
- integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
-
-safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
- integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
-
-semver@^5.5.0:
- version "5.6.0"
- resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004"
- integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==
-
-shebang-command@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
- integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=
- dependencies:
- shebang-regex "^1.0.0"
-
-shebang-regex@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
- integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=
-
-signal-exit@^3.0.0:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
- integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=
-
-slice-ansi@0.0.4:
- version "0.0.4"
- resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35"
- integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=
-
-sshpk@^1.7.0:
- version "1.16.0"
- resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.0.tgz#1d4963a2fbffe58050aa9084ca20be81741c07de"
- integrity sha512-Zhev35/y7hRMcID/upReIvRse+I9SVhyVre/KTJSJQWMz3C3+G+HpO7m1wK/yckEtujKZ7dS4hkVxAnmHaIGVQ==
- dependencies:
- asn1 "~0.2.3"
- assert-plus "^1.0.0"
- bcrypt-pbkdf "^1.0.0"
- dashdash "^1.12.0"
- ecc-jsbn "~0.1.1"
- getpass "^0.1.1"
- jsbn "~0.1.0"
- safer-buffer "^2.0.2"
- tweetnacl "~0.14.0"
-
-stream-to-observable@^0.1.0:
- version "0.1.0"
- resolved "https://registry.yarnpkg.com/stream-to-observable/-/stream-to-observable-0.1.0.tgz#45bf1d9f2d7dc09bed81f1c307c430e68b84cffe"
- integrity sha1-Rb8dny19wJvtgfHDB8Qw5ouEz/4=
-
-string-width@^1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
- integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=
- dependencies:
- code-point-at "^1.0.0"
- is-fullwidth-code-point "^1.0.0"
- strip-ansi "^3.0.0"
-
-string_decoder@~1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
- integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
- dependencies:
- safe-buffer "~5.1.0"
-
-strip-ansi@^3.0.0, strip-ansi@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
- integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=
- dependencies:
- ansi-regex "^2.0.0"
-
-strip-eof@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
- integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=
-
-supports-color@5.1.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.1.0.tgz#058a021d1b619f7ddf3980d712ea3590ce7de3d5"
- integrity sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==
- dependencies:
- has-flag "^2.0.0"
-
-supports-color@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
- integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=
-
-supports-color@^5.3.0:
- version "5.5.0"
- resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
- integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
- dependencies:
- has-flag "^3.0.0"
-
-symbol-observable@1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4"
- integrity sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=
-
-throttleit@~0.0.2:
- version "0.0.2"
- resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-0.0.2.tgz#cfedf88e60c00dd9697b61fdd2a8343a9b680eaf"
- integrity sha1-z+34jmDADdlpe2H90qg0OptoDq8=
-
-tmp@0.0.31:
- version "0.0.31"
- resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.31.tgz#8f38ab9438e17315e5dbd8b3657e8bfb277ae4a7"
- integrity sha1-jzirlDjhcxXl29izZX6L+yd65Kc=
- dependencies:
- os-tmpdir "~1.0.1"
-
-tough-cookie@~2.3.3:
- version "2.3.4"
- resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655"
- integrity sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==
- dependencies:
- punycode "^1.4.1"
-
-tunnel-agent@^0.6.0:
- version "0.6.0"
- resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
- integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=
- dependencies:
- safe-buffer "^5.0.1"
-
-tweetnacl@^0.14.3, tweetnacl@~0.14.0:
- version "0.14.5"
- resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
- integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
-
-typedarray@^0.0.6:
- version "0.0.6"
- resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
- integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
-
-universalify@^0.1.0:
- version "0.1.2"
- resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
- integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
-
-url@0.11.0:
- version "0.11.0"
- resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
- integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=
- dependencies:
- punycode "1.3.2"
- querystring "0.2.0"
-
-util-deprecate@~1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
- integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
-
-uuid@^3.1.0:
- version "3.3.2"
- resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
- integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==
-
-verror@1.10.0:
- version "1.10.0"
- resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
- integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
- dependencies:
- assert-plus "^1.0.0"
- core-util-is "1.0.2"
- extsprintf "^1.2.0"
-
-which@^1.2.9:
- version "1.3.1"
- resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
- integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
- dependencies:
- isexe "^2.0.0"
-
-wrappy@1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
- integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
-
-yauzl@2.4.1:
- version "2.4.1"
- resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.4.1.tgz#9528f442dab1b2284e58b4379bb194e22e0c4005"
- integrity sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=
- dependencies:
- fd-slicer "~1.0.1"
-
-yauzl@2.8.0:
- version "2.8.0"
- resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.8.0.tgz#79450aff22b2a9c5a41ef54e02db907ccfbf9ee2"
- integrity sha1-eUUK/yKyqcWkHvVOAtuQfM+/nuI=
- dependencies:
- buffer-crc32 "~0.2.3"
- fd-slicer "~1.0.1"