Merge branch 'develop' into item-group-filter-portal
This commit is contained in:
commit
ffd30beeca
@ -10,13 +10,15 @@ frappe.ui.form.on('Process Deferred Accounting', {
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
if (frm.doc.company) {
|
||||
type: function(frm) {
|
||||
if (frm.doc.company && frm.doc.type) {
|
||||
frm.set_query("account", function() {
|
||||
return {
|
||||
filters: {
|
||||
'company': frm.doc.company,
|
||||
'root_type': 'Liability',
|
||||
'root_type': frm.doc.type === 'Income' ? 'Liability' : 'Asset',
|
||||
'is_group': 0
|
||||
}
|
||||
};
|
||||
|
@ -60,6 +60,7 @@
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: doc.type",
|
||||
"fieldname": "account",
|
||||
"fieldtype": "Link",
|
||||
"label": "Account",
|
||||
@ -73,9 +74,10 @@
|
||||
"reqd": 1
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-02-06 18:18:09.852844",
|
||||
"modified": "2020-09-03 18:07:02.463754",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Process Deferred Accounting",
|
||||
|
@ -73,8 +73,8 @@ frappe.ui.form.on('Loan', {
|
||||
|
||||
loan_type: function(frm) {
|
||||
frm.toggle_reqd("repayment_method", frm.doc.is_term_loan);
|
||||
frm.toggle_display("repayment_method", 1 - frm.doc.is_term_loan);
|
||||
frm.toggle_display("repayment_periods", s1 - frm.doc.is_term_loan);
|
||||
frm.toggle_display("repayment_method", frm.doc.is_term_loan);
|
||||
frm.toggle_display("repayment_periods", frm.doc.is_term_loan);
|
||||
},
|
||||
|
||||
|
||||
@ -119,12 +119,10 @@ frappe.ui.form.on('Loan', {
|
||||
|
||||
create_loan_security_unpledge: function(frm) {
|
||||
frappe.call({
|
||||
method: "erpnext.loan_management.doctype.loan.loan.create_loan_security_unpledge",
|
||||
method: "erpnext.loan_management.doctype.loan.loan.unpledge_security",
|
||||
args : {
|
||||
"loan": frm.doc.name,
|
||||
"applicant_type": frm.doc.applicant_type,
|
||||
"applicant": frm.doc.applicant,
|
||||
"company": frm.doc.company
|
||||
"as_dict": 1
|
||||
},
|
||||
callback: function(r) {
|
||||
if (r.message)
|
||||
|
@ -7,7 +7,7 @@ import frappe, math, json
|
||||
import erpnext
|
||||
from frappe import _
|
||||
from frappe.utils import flt, rounded, add_months, nowdate, getdate, now_datetime
|
||||
|
||||
from erpnext.loan_management.doctype.loan_security_unpledge.loan_security_unpledge import get_pledged_security_qty
|
||||
from erpnext.controllers.accounts_controller import AccountsController
|
||||
|
||||
class Loan(AccountsController):
|
||||
@ -223,30 +223,52 @@ def make_repayment_entry(loan, applicant_type, applicant, loan_type, company, as
|
||||
return repayment_entry
|
||||
|
||||
@frappe.whitelist()
|
||||
def create_loan_security_unpledge(loan, applicant_type, applicant, company, as_dict=1):
|
||||
loan_security_pledge_details = frappe.db.sql("""
|
||||
SELECT p.loan_security, sum(p.qty) as qty
|
||||
FROM `tabLoan Security Pledge` lsp , `tabPledge` p
|
||||
WHERE p.parent = lsp.name AND lsp.loan = %s AND lsp.docstatus = 1
|
||||
GROUP BY p.loan_security
|
||||
""",(loan), as_dict=1)
|
||||
def unpledge_security(loan=None, loan_security_pledge=None, as_dict=0, save=0, submit=0, approve=0):
|
||||
# if loan is passed it will be considered as full unpledge
|
||||
if loan:
|
||||
pledge_qty_map = get_pledged_security_qty(loan)
|
||||
loan_doc = frappe.get_doc('Loan', loan)
|
||||
unpledge_request = create_loan_security_unpledge(pledge_qty_map, loan_doc.name, loan_doc.company,
|
||||
loan_doc.applicant_type, loan_doc.applicant)
|
||||
# will unpledge qty based on loan security pledge
|
||||
elif loan_security_pledge:
|
||||
security_map = {}
|
||||
pledge_doc = frappe.get_doc('Loan Security Pledge', loan_security_pledge)
|
||||
for security in pledge_doc.securities:
|
||||
security_map.setdefault(security.loan_security, security.qty)
|
||||
|
||||
unpledge_request = create_loan_security_unpledge(security_map, pledge_doc.loan,
|
||||
pledge_doc.company, pledge_doc.applicant_type, pledge_doc.applicant)
|
||||
|
||||
if approve:
|
||||
unpledge_request.status = 'Approved'
|
||||
|
||||
if save:
|
||||
unpledge_request.save()
|
||||
|
||||
if submit:
|
||||
unpledge_request.submit()
|
||||
|
||||
if as_dict:
|
||||
return unpledge_request
|
||||
else:
|
||||
return unpledge_request
|
||||
|
||||
def create_loan_security_unpledge(unpledge_map, loan, company, applicant_type, applicant):
|
||||
unpledge_request = frappe.new_doc("Loan Security Unpledge")
|
||||
unpledge_request.applicant_type = applicant_type
|
||||
unpledge_request.applicant = applicant
|
||||
unpledge_request.loan = loan
|
||||
unpledge_request.company = company
|
||||
|
||||
for loan_security in loan_security_pledge_details:
|
||||
unpledge_request.append('securities', {
|
||||
"loan_security": loan_security.loan_security,
|
||||
"qty": loan_security.qty
|
||||
})
|
||||
for security, qty in unpledge_map.items():
|
||||
if qty:
|
||||
unpledge_request.append('securities', {
|
||||
"loan_security": security,
|
||||
"qty": qty
|
||||
})
|
||||
|
||||
if as_dict:
|
||||
return unpledge_request.as_dict()
|
||||
else:
|
||||
return unpledge_request
|
||||
return unpledge_request
|
||||
|
||||
|
||||
|
||||
|
@ -14,7 +14,7 @@ from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_
|
||||
process_loan_interest_accrual_for_term_loans)
|
||||
from erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual import days_in_year
|
||||
from erpnext.loan_management.doctype.process_loan_security_shortfall.process_loan_security_shortfall import create_process_loan_security_shortfall
|
||||
from erpnext.loan_management.doctype.loan.loan import create_loan_security_unpledge
|
||||
from erpnext.loan_management.doctype.loan.loan import unpledge_security
|
||||
from erpnext.loan_management.doctype.loan_security_unpledge.loan_security_unpledge import get_pledged_security_qty
|
||||
from erpnext.loan_management.doctype.loan_application.loan_application import create_pledge
|
||||
from erpnext.loan_management.doctype.loan_disbursement.loan_disbursement import get_disbursal_amount
|
||||
@ -307,7 +307,7 @@ class TestLoan(unittest.TestCase):
|
||||
loan.load_from_db()
|
||||
self.assertEquals(loan.status, "Loan Closure Requested")
|
||||
|
||||
unpledge_request = create_loan_security_unpledge(loan.name, loan.applicant_type, loan.applicant, loan.company, as_dict=0)
|
||||
unpledge_request = unpledge_security(loan=loan.name, save=1)
|
||||
unpledge_request.submit()
|
||||
unpledge_request.status = 'Approved'
|
||||
unpledge_request.save()
|
||||
|
@ -21,6 +21,10 @@
|
||||
"total_security_value",
|
||||
"column_break_11",
|
||||
"maximum_loan_value",
|
||||
"more_information_section",
|
||||
"reference_no",
|
||||
"column_break_18",
|
||||
"description",
|
||||
"amended_from"
|
||||
],
|
||||
"fields": [
|
||||
@ -129,11 +133,34 @@
|
||||
"label": "Applicant Type",
|
||||
"options": "Employee\nMember\nCustomer",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"fieldname": "more_information_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "More Information"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "reference_no",
|
||||
"fieldtype": "Data",
|
||||
"label": "Reference No"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_18",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Text",
|
||||
"label": "Description"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-07-02 23:38:24.002382",
|
||||
"modified": "2020-09-04 22:38:19.894488",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Loan Management",
|
||||
"name": "Loan Security Pledge",
|
||||
|
@ -16,6 +16,10 @@
|
||||
"status",
|
||||
"loan_security_details_section",
|
||||
"securities",
|
||||
"more_information_section",
|
||||
"reference_no",
|
||||
"column_break_13",
|
||||
"description",
|
||||
"amended_from"
|
||||
],
|
||||
"fields": [
|
||||
@ -95,11 +99,34 @@
|
||||
"label": "Applicant Type",
|
||||
"options": "Employee\nMember\nCustomer",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"fieldname": "more_information_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "More Information"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "reference_no",
|
||||
"fieldtype": "Data",
|
||||
"label": "Reference No"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_13",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Text",
|
||||
"label": "Description"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-05-05 07:23:18.440058",
|
||||
"modified": "2020-09-04 22:39:57.756146",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Loan Management",
|
||||
"name": "Loan Security Unpledge",
|
||||
|
@ -17,10 +17,12 @@ class LoanSecurityUnpledge(Document):
|
||||
self.validate_unpledge_qty()
|
||||
|
||||
def on_cancel(self):
|
||||
self.update_loan_security_pledge(cancel=1)
|
||||
self.update_loan_status(cancel=1)
|
||||
self.db_set('status', 'Requested')
|
||||
|
||||
def on_submit(self):
|
||||
self.approve()
|
||||
|
||||
def validate_duplicate_securities(self):
|
||||
security_list = []
|
||||
for d in self.securities:
|
||||
@ -50,8 +52,7 @@ class LoanSecurityUnpledge(Document):
|
||||
security_value = 0
|
||||
|
||||
for security in self.securities:
|
||||
pledged_qty = pledge_qty_map.get(security.loan_security)
|
||||
|
||||
pledged_qty = pledge_qty_map.get(security.loan_security, 0)
|
||||
if security.qty > pledged_qty:
|
||||
frappe.throw(_("""Row {0}: {1} {2} of {3} is pledged against Loan {4}.
|
||||
You are trying to unpledge more""").format(security.idx, pledged_qty, security.uom,
|
||||
@ -60,16 +61,23 @@ class LoanSecurityUnpledge(Document):
|
||||
qty_after_unpledge = pledged_qty - security.qty
|
||||
ltv_ratio = ltv_ratio_map.get(security.loan_security_type)
|
||||
|
||||
security_value += qty_after_unpledge * loan_security_price_map.get(security.loan_security)
|
||||
current_price = loan_security_price_map.get(security.loan_security)
|
||||
if not current_price:
|
||||
frappe.throw(_("No valid Loan Security Price found for {0}").format(frappe.bold(security.loan_security)))
|
||||
|
||||
security_value += qty_after_unpledge * current_price
|
||||
|
||||
if not security_value and flt(pending_principal_amount, 2) > 0:
|
||||
frappe.throw("Cannot Unpledge, loan to value ratio is breaching")
|
||||
|
||||
if security_value and (pending_principal_amount/security_value) * 100 > ltv_ratio:
|
||||
if security_value and flt(pending_principal_amount/security_value) * 100 > ltv_ratio:
|
||||
frappe.throw("Cannot Unpledge, loan to value ratio is breaching")
|
||||
|
||||
def on_update_after_submit(self):
|
||||
if self.status == "Approved":
|
||||
self.approve()
|
||||
|
||||
def approve(self):
|
||||
if self.status == "Approved" and not self.unpledge_time:
|
||||
self.update_loan_status()
|
||||
self.db_set('unpledge_time', get_datetime())
|
||||
|
||||
|
@ -158,7 +158,7 @@ def create_member_subscription_order(user_details):
|
||||
|
||||
return subscription
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
@frappe.whitelist()
|
||||
def register_member(fullname, email, rzpay_plan_id, subscription_id, pan=None, mobile=None):
|
||||
plan = get_membership_type(rzpay_plan_id)
|
||||
if not plan:
|
||||
|
@ -20,6 +20,7 @@ def after_install():
|
||||
frappe.get_doc({'doctype': "Role", "role_name": "Analytics"}).insert()
|
||||
set_single_defaults()
|
||||
create_compact_item_print_custom_field()
|
||||
create_print_uom_after_qty_custom_field()
|
||||
create_print_zero_amount_taxes_custom_field()
|
||||
add_all_roles_to("Administrator")
|
||||
create_default_cash_flow_mapper_templates()
|
||||
@ -66,6 +67,16 @@ def create_compact_item_print_custom_field():
|
||||
})
|
||||
|
||||
|
||||
def create_print_uom_after_qty_custom_field():
|
||||
create_custom_field('Print Settings', {
|
||||
'label': _('Print UOM after Quantity'),
|
||||
'fieldname': 'print_uom_after_quantity',
|
||||
'fieldtype': 'Check',
|
||||
'default': 0,
|
||||
'insert_after': 'compact_item_print'
|
||||
})
|
||||
|
||||
|
||||
def create_print_zero_amount_taxes_custom_field():
|
||||
create_custom_field('Print Settings', {
|
||||
'label': _('Print taxes with zero amount'),
|
||||
|
@ -123,7 +123,8 @@ def get_all_suppliers(date_range, company, field, limit = None):
|
||||
if field == "outstanding_amount":
|
||||
filters = [['docstatus', '=', '1'], ['company', '=', company]]
|
||||
if date_range:
|
||||
filters.append(['posting_date', 'between' [date_range[0], date_range[1]]])
|
||||
date_range = frappe.parse_json(date_range)
|
||||
filters.append(['posting_date', 'between', [date_range[0], date_range[1]]])
|
||||
return frappe.db.get_all('Purchase Invoice',
|
||||
fields = ['supplier as name', 'sum(outstanding_amount) as value'],
|
||||
filters = filters,
|
||||
|
@ -513,7 +513,7 @@ class StockEntry(StockController):
|
||||
d.basic_amount = flt((raw_material_cost - scrap_material_cost), d.precision("basic_amount"))
|
||||
elif self.purpose == "Repack" and total_fg_qty and not d.set_basic_rate_manually:
|
||||
d.basic_rate = flt(raw_material_cost) / flt(total_fg_qty)
|
||||
d.basic_amount = d.basic_rate * d.qty
|
||||
d.basic_amount = d.basic_rate * flt(d.qty)
|
||||
|
||||
def distribute_additional_costs(self):
|
||||
if self.purpose == "Material Issue":
|
||||
|
@ -258,6 +258,7 @@ class StockReconciliation(StockController):
|
||||
|
||||
sl_entries.append(args)
|
||||
|
||||
qty_after_transaction = 0
|
||||
for serial_no in serial_nos:
|
||||
args = self.get_sle_for_items(row, [serial_no])
|
||||
|
||||
@ -271,11 +272,19 @@ class StockReconciliation(StockController):
|
||||
if previous_sle and row.warehouse != previous_sle.get("warehouse"):
|
||||
# If serial no exists in different warehouse
|
||||
|
||||
warehouse = previous_sle.get("warehouse", '') or row.warehouse
|
||||
|
||||
if not qty_after_transaction:
|
||||
qty_after_transaction = get_stock_balance(row.item_code,
|
||||
warehouse, self.posting_date, self.posting_time)
|
||||
|
||||
qty_after_transaction -= 1
|
||||
|
||||
new_args = args.copy()
|
||||
new_args.update({
|
||||
'actual_qty': -1,
|
||||
'qty_after_transaction': cint(previous_sle.get('qty_after_transaction')) - 1,
|
||||
'warehouse': previous_sle.get("warehouse", '') or row.warehouse,
|
||||
'qty_after_transaction': qty_after_transaction,
|
||||
'warehouse': warehouse,
|
||||
'valuation_rate': previous_sle.get("valuation_rate")
|
||||
})
|
||||
|
||||
|
@ -1,6 +1,15 @@
|
||||
{% if (doc.uom and not doc.is_print_hide("uom")) %}
|
||||
<small class="pull-left">{{ _(doc.uom) }}</small>
|
||||
{% elif (doc.stock_uom and not doc.is_print_hide("stock_uom")) %}
|
||||
<small class="pull-left">{{ _(doc.stock_uom) }}</small>
|
||||
{% set qty_first=frappe.db.get_single_value("Print Settings", "print_uom_after_quantity") %}
|
||||
{% if qty_first %}
|
||||
{{ doc.get_formatted("qty", doc) }}
|
||||
{% if (doc.uom and not doc.is_print_hide("uom")) %} {{ _(doc.uom) }}
|
||||
{% elif (doc.stock_uom and not doc.is_print_hide("stock_uom")) %} {{ _(doc.stock_uom) }}
|
||||
{%- endif %}
|
||||
{% else %}
|
||||
{% if (doc.uom and not doc.is_print_hide("uom")) %}
|
||||
<small class="pull-left">{{ _(doc.uom) }}</small>
|
||||
{% elif (doc.stock_uom and not doc.is_print_hide("stock_uom")) %}
|
||||
<small class="pull-left">{{ _(doc.stock_uom) }}</small>
|
||||
{%- endif %}
|
||||
{{ doc.get_formatted("qty", doc) }}
|
||||
{%- endif %}
|
||||
{{ doc.get_formatted("qty", doc) }}
|
||||
|
||||
|
@ -82,6 +82,7 @@ def get_price(item_code, price_list, customer_group, company, qty=1):
|
||||
pricing_rule = get_pricing_rule_for_item(frappe._dict({
|
||||
"item_code": item_code,
|
||||
"qty": qty,
|
||||
"stock_qty": qty,
|
||||
"transaction_type": "selling",
|
||||
"price_list": price_list,
|
||||
"customer_group": customer_group,
|
||||
|
22
yarn.lock
22
yarn.lock
@ -282,9 +282,9 @@ balanced-match@^1.0.0:
|
||||
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
|
||||
|
||||
bl@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/bl/-/bl-3.0.0.tgz#3611ec00579fd18561754360b21e9f784500ff88"
|
||||
integrity sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A==
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/bl/-/bl-3.0.1.tgz#1cbb439299609e419b5a74d7fce2f8b37d8e5c6f"
|
||||
integrity sha512-jrCW5ZhfQ/Vt07WX1Ngs+yn9BDqPL/gw28S7s9H6QK/gupnizNzJAss5akW20ISgOrbLTlXOOCTJeNUQqruAWQ==
|
||||
dependencies:
|
||||
readable-stream "^3.0.1"
|
||||
|
||||
@ -866,12 +866,12 @@ inflight@^1.0.4:
|
||||
once "^1.3.0"
|
||||
wrappy "1"
|
||||
|
||||
inherits@2, inherits@^2.0.3, inherits@~2.0.3:
|
||||
inherits@2, inherits@~2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
||||
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
|
||||
|
||||
inherits@2.0.4, inherits@~2.0.1:
|
||||
inherits@2.0.4, inherits@^2.0.3, inherits@~2.0.1:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
@ -1447,9 +1447,9 @@ readable-stream@2, readable-stream@~2.3.6:
|
||||
util-deprecate "~1.0.1"
|
||||
|
||||
readable-stream@^3.0.1, readable-stream@^3.1.1:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.5.0.tgz#465d70e6d1087f6162d079cd0b5db7fbebfd1606"
|
||||
integrity sha512-gSz026xs2LfxBPudDuI41V1lka8cxg64E66SGe78zJlsUofOg/yqwezdIcdfwik6B4h8LFmWPA9ef9X3FiNFLA==
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
|
||||
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
|
||||
dependencies:
|
||||
inherits "^2.0.3"
|
||||
string_decoder "^1.1.1"
|
||||
@ -1505,9 +1505,9 @@ safe-buffer@^5.0.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
|
||||
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
|
||||
|
||||
safe-buffer@~5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519"
|
||||
integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
||||
|
||||
"safer-buffer@>= 2.1.2 < 3":
|
||||
version "2.1.2"
|
||||
|
Loading…
x
Reference in New Issue
Block a user