Compare commits
44 Commits
revert-339
...
update-cod
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
320f3c1ac0 | ||
|
|
4d79ffe3c6 | ||
|
|
e8b8c51d82 | ||
|
|
3f44ef8790 | ||
|
|
c793fb0bb4 | ||
|
|
c7a540b7e2 | ||
|
|
6c6195bae6 | ||
|
|
0cd69c8700 | ||
|
|
ffa9c6e4d9 | ||
|
|
d3ff289779 | ||
|
|
ef56060166 | ||
|
|
2e43123048 | ||
|
|
9235918d65 | ||
|
|
d5b7f2e49e | ||
|
|
8e40c04494 | ||
|
|
f7fd30fecf | ||
|
|
e69ea17f59 | ||
|
|
5b6128848f | ||
|
|
662ebc5c1a | ||
|
|
d003370f61 | ||
|
|
b0cfb0b9ef | ||
|
|
a58f2e6c03 | ||
|
|
75d9dbca43 | ||
|
|
447310702e | ||
|
|
960085853a | ||
|
|
5faa62c49a | ||
|
|
3014bac293 | ||
|
|
00a4191966 | ||
|
|
770369e5c1 | ||
|
|
86be259341 | ||
|
|
ce748cec3a | ||
|
|
231fe4156f | ||
|
|
c533213225 | ||
|
|
a67284e96d | ||
|
|
4f2553e7b6 | ||
|
|
192a3395a5 | ||
|
|
e5a2b15fba | ||
|
|
148703bfc2 | ||
|
|
ce3f9622cb | ||
|
|
48bb2c942b | ||
|
|
77f6789706 | ||
|
|
b9a7ff7c3d | ||
|
|
b0e8dfc1d0 | ||
|
|
d76759e066 |
@@ -4,7 +4,7 @@
|
|||||||
# the repo. Unless a later match takes precedence,
|
# the repo. Unless a later match takes precedence,
|
||||||
|
|
||||||
erpnext/accounts/ @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
|
erpnext/accounts/ @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
|
||||||
erpnext/assets/ @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
|
erpnext/assets/ @anandbaburajan @deepeshgarg007
|
||||||
erpnext/loan_management/ @nextchamp-saqib @deepeshgarg007
|
erpnext/loan_management/ @nextchamp-saqib @deepeshgarg007
|
||||||
erpnext/regional @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
|
erpnext/regional @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
|
||||||
erpnext/selling @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
|
erpnext/selling @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
|
||||||
@@ -16,6 +16,7 @@ erpnext/maintenance/ @rohitwaghchaure @s-aga-r
|
|||||||
erpnext/manufacturing/ @rohitwaghchaure @s-aga-r
|
erpnext/manufacturing/ @rohitwaghchaure @s-aga-r
|
||||||
erpnext/quality_management/ @rohitwaghchaure @s-aga-r
|
erpnext/quality_management/ @rohitwaghchaure @s-aga-r
|
||||||
erpnext/stock/ @rohitwaghchaure @s-aga-r
|
erpnext/stock/ @rohitwaghchaure @s-aga-r
|
||||||
|
erpnext/subcontracting @rohitwaghchaure @s-aga-r
|
||||||
|
|
||||||
erpnext/crm/ @NagariaHussain
|
erpnext/crm/ @NagariaHussain
|
||||||
erpnext/education/ @rutwikhdev
|
erpnext/education/ @rutwikhdev
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class Dunning(AccountsController):
|
|||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
if self.dunning_amount:
|
if self.dunning_amount:
|
||||||
self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry")
|
self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry", "Payment Ledger Entry")
|
||||||
make_reverse_gl_entries(voucher_type=self.doctype, voucher_no=self.name)
|
make_reverse_gl_entries(voucher_type=self.doctype, voucher_no=self.name)
|
||||||
|
|
||||||
def make_gl_entries(self):
|
def make_gl_entries(self):
|
||||||
|
|||||||
@@ -239,7 +239,7 @@
|
|||||||
"depends_on": "paid_from",
|
"depends_on": "paid_from",
|
||||||
"fieldname": "paid_from_account_currency",
|
"fieldname": "paid_from_account_currency",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Account Currency",
|
"label": "Account Currency (From)",
|
||||||
"options": "Currency",
|
"options": "Currency",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
@@ -249,7 +249,7 @@
|
|||||||
"depends_on": "paid_from",
|
"depends_on": "paid_from",
|
||||||
"fieldname": "paid_from_account_balance",
|
"fieldname": "paid_from_account_balance",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Account Balance",
|
"label": "Account Balance (From)",
|
||||||
"options": "paid_from_account_currency",
|
"options": "paid_from_account_currency",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
@@ -272,7 +272,7 @@
|
|||||||
"depends_on": "paid_to",
|
"depends_on": "paid_to",
|
||||||
"fieldname": "paid_to_account_currency",
|
"fieldname": "paid_to_account_currency",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Account Currency",
|
"label": "Account Currency (To)",
|
||||||
"options": "Currency",
|
"options": "Currency",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
@@ -282,7 +282,7 @@
|
|||||||
"depends_on": "paid_to",
|
"depends_on": "paid_to",
|
||||||
"fieldname": "paid_to_account_balance",
|
"fieldname": "paid_to_account_balance",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Account Balance",
|
"label": "Account Balance (To)",
|
||||||
"options": "paid_to_account_currency",
|
"options": "paid_to_account_currency",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
@@ -304,7 +304,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "source_exchange_rate",
|
"fieldname": "source_exchange_rate",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"label": "Exchange Rate",
|
"label": "Source Exchange Rate",
|
||||||
"precision": "9",
|
"precision": "9",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
@@ -334,7 +334,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "target_exchange_rate",
|
"fieldname": "target_exchange_rate",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"label": "Exchange Rate",
|
"label": "Target Exchange Rate",
|
||||||
"precision": "9",
|
"precision": "9",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
@@ -633,14 +633,14 @@
|
|||||||
"depends_on": "eval:doc.party_type == 'Supplier'",
|
"depends_on": "eval:doc.party_type == 'Supplier'",
|
||||||
"fieldname": "purchase_taxes_and_charges_template",
|
"fieldname": "purchase_taxes_and_charges_template",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Taxes and Charges Template",
|
"label": "Purchase Taxes and Charges Template",
|
||||||
"options": "Purchase Taxes and Charges Template"
|
"options": "Purchase Taxes and Charges Template"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval: doc.party_type == 'Customer'",
|
"depends_on": "eval: doc.party_type == 'Customer'",
|
||||||
"fieldname": "sales_taxes_and_charges_template",
|
"fieldname": "sales_taxes_and_charges_template",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Taxes and Charges Template",
|
"label": "Sales Taxes and Charges Template",
|
||||||
"options": "Sales Taxes and Charges Template"
|
"options": "Sales Taxes and Charges Template"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -733,7 +733,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-12-08 16:25:43.824051",
|
"modified": "2023-02-14 04:52:30.478523",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Payment Entry",
|
"name": "Payment Entry",
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ class PaymentReconciliation(Document):
|
|||||||
def allocate_entries(self, args):
|
def allocate_entries(self, args):
|
||||||
self.validate_entries()
|
self.validate_entries()
|
||||||
|
|
||||||
invoice_exchange_map = self.get_invoice_exchange_map(args.get("invoices"))
|
invoice_exchange_map = self.get_invoice_exchange_map(args.get("invoices"), args.get("payments"))
|
||||||
default_exchange_gain_loss_account = frappe.get_cached_value(
|
default_exchange_gain_loss_account = frappe.get_cached_value(
|
||||||
"Company", self.company, "exchange_gain_loss_account"
|
"Company", self.company, "exchange_gain_loss_account"
|
||||||
)
|
)
|
||||||
@@ -253,6 +253,9 @@ class PaymentReconciliation(Document):
|
|||||||
pay["amount"] = 0
|
pay["amount"] = 0
|
||||||
|
|
||||||
inv["exchange_rate"] = invoice_exchange_map.get(inv.get("invoice_number"))
|
inv["exchange_rate"] = invoice_exchange_map.get(inv.get("invoice_number"))
|
||||||
|
if pay.get("reference_type") in ["Sales Invoice", "Purchase Invoice"]:
|
||||||
|
pay["exchange_rate"] = invoice_exchange_map.get(pay.get("reference_name"))
|
||||||
|
|
||||||
res.difference_amount = self.get_difference_amount(pay, inv, res["allocated_amount"])
|
res.difference_amount = self.get_difference_amount(pay, inv, res["allocated_amount"])
|
||||||
res.difference_account = default_exchange_gain_loss_account
|
res.difference_account = default_exchange_gain_loss_account
|
||||||
res.exchange_rate = inv.get("exchange_rate")
|
res.exchange_rate = inv.get("exchange_rate")
|
||||||
@@ -407,13 +410,21 @@ class PaymentReconciliation(Document):
|
|||||||
if not self.get("payments"):
|
if not self.get("payments"):
|
||||||
frappe.throw(_("No records found in the Payments table"))
|
frappe.throw(_("No records found in the Payments table"))
|
||||||
|
|
||||||
def get_invoice_exchange_map(self, invoices):
|
def get_invoice_exchange_map(self, invoices, payments):
|
||||||
sales_invoices = [
|
sales_invoices = [
|
||||||
d.get("invoice_number") for d in invoices if d.get("invoice_type") == "Sales Invoice"
|
d.get("invoice_number") for d in invoices if d.get("invoice_type") == "Sales Invoice"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
sales_invoices.extend(
|
||||||
|
[d.get("reference_name") for d in payments if d.get("reference_type") == "Sales Invoice"]
|
||||||
|
)
|
||||||
purchase_invoices = [
|
purchase_invoices = [
|
||||||
d.get("invoice_number") for d in invoices if d.get("invoice_type") == "Purchase Invoice"
|
d.get("invoice_number") for d in invoices if d.get("invoice_type") == "Purchase Invoice"
|
||||||
]
|
]
|
||||||
|
purchase_invoices.extend(
|
||||||
|
[d.get("reference_name") for d in payments if d.get("reference_type") == "Purchase Invoice"]
|
||||||
|
)
|
||||||
|
|
||||||
invoice_exchange_map = frappe._dict()
|
invoice_exchange_map = frappe._dict()
|
||||||
|
|
||||||
if sales_invoices:
|
if sales_invoices:
|
||||||
|
|||||||
@@ -473,6 +473,11 @@ class TestPaymentReconciliation(FrappeTestCase):
|
|||||||
invoices = [x.as_dict() for x in pr.get("invoices")]
|
invoices = [x.as_dict() for x in pr.get("invoices")]
|
||||||
payments = [x.as_dict() for x in pr.get("payments")]
|
payments = [x.as_dict() for x in pr.get("payments")]
|
||||||
pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments}))
|
pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments}))
|
||||||
|
|
||||||
|
# Cr Note and Invoice are of the same currency. There shouldn't any difference amount.
|
||||||
|
for row in pr.allocation:
|
||||||
|
self.assertEqual(flt(row.get("difference_amount")), 0.0)
|
||||||
|
|
||||||
pr.reconcile()
|
pr.reconcile()
|
||||||
|
|
||||||
pr.get_unreconciled_entries()
|
pr.get_unreconciled_entries()
|
||||||
@@ -506,6 +511,11 @@ class TestPaymentReconciliation(FrappeTestCase):
|
|||||||
payments = [x.as_dict() for x in pr.get("payments")]
|
payments = [x.as_dict() for x in pr.get("payments")]
|
||||||
pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments}))
|
pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments}))
|
||||||
pr.allocation[0].allocated_amount = allocated_amount
|
pr.allocation[0].allocated_amount = allocated_amount
|
||||||
|
|
||||||
|
# Cr Note and Invoice are of the same currency. There shouldn't any difference amount.
|
||||||
|
for row in pr.allocation:
|
||||||
|
self.assertEqual(flt(row.get("difference_amount")), 0.0)
|
||||||
|
|
||||||
pr.reconcile()
|
pr.reconcile()
|
||||||
|
|
||||||
# assert outstanding
|
# assert outstanding
|
||||||
|
|||||||
@@ -45,11 +45,10 @@ class PaymentRequest(Document):
|
|||||||
frappe.throw(_("To create a Payment Request reference document is required"))
|
frappe.throw(_("To create a Payment Request reference document is required"))
|
||||||
|
|
||||||
def validate_payment_request_amount(self):
|
def validate_payment_request_amount(self):
|
||||||
existing_payment_request_amount = get_existing_payment_request_amount(
|
existing_payment_request_amount = flt(
|
||||||
self.reference_doctype, self.reference_name
|
get_existing_payment_request_amount(self.reference_doctype, self.reference_name)
|
||||||
)
|
)
|
||||||
|
|
||||||
if existing_payment_request_amount:
|
|
||||||
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
|
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
|
||||||
if not hasattr(ref_doc, "order_type") or getattr(ref_doc, "order_type") != "Shopping Cart":
|
if not hasattr(ref_doc, "order_type") or getattr(ref_doc, "order_type") != "Shopping Cart":
|
||||||
ref_amount = get_amount(ref_doc, self.payment_account)
|
ref_amount = get_amount(ref_doc, self.payment_account)
|
||||||
|
|||||||
@@ -472,7 +472,7 @@
|
|||||||
"description": "If rate is zero them item will be treated as \"Free Item\"",
|
"description": "If rate is zero them item will be treated as \"Free Item\"",
|
||||||
"fieldname": "free_item_rate",
|
"fieldname": "free_item_rate",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Rate"
|
"label": "Free Item Rate"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"collapsible": 1,
|
"collapsible": 1,
|
||||||
@@ -608,7 +608,7 @@
|
|||||||
"icon": "fa fa-gift",
|
"icon": "fa fa-gift",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-10-13 19:05:35.056304",
|
"modified": "2023-02-14 04:53:34.887358",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Pricing Rule",
|
"name": "Pricing Rule",
|
||||||
|
|||||||
@@ -135,6 +135,34 @@ def get_assets(filters):
|
|||||||
where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s and ads.asset = a.name and ads.docstatus=1 and ads.name = ds.parent and ifnull(ds.journal_entry, '') != ''
|
where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s and ads.asset = a.name and ads.docstatus=1 and ads.name = ds.parent and ifnull(ds.journal_entry, '') != ''
|
||||||
group by a.asset_category
|
group by a.asset_category
|
||||||
union
|
union
|
||||||
|
SELECT a.asset_category,
|
||||||
|
ifnull(sum(case when gle.posting_date < %(from_date)s and (ifnull(a.disposal_date, 0) = 0 or a.disposal_date >= %(from_date)s) then
|
||||||
|
gle.debit
|
||||||
|
else
|
||||||
|
0
|
||||||
|
end), 0) as accumulated_depreciation_as_on_from_date,
|
||||||
|
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 and a.disposal_date >= %(from_date)s
|
||||||
|
and a.disposal_date <= %(to_date)s and gle.posting_date <= a.disposal_date then
|
||||||
|
gle.debit
|
||||||
|
else
|
||||||
|
0
|
||||||
|
end), 0) as depreciation_eliminated_during_the_period,
|
||||||
|
ifnull(sum(case when gle.posting_date >= %(from_date)s and gle.posting_date <= %(to_date)s
|
||||||
|
and (ifnull(a.disposal_date, 0) = 0 or gle.posting_date <= a.disposal_date) then
|
||||||
|
gle.debit
|
||||||
|
else
|
||||||
|
0
|
||||||
|
end), 0) as depreciation_amount_during_the_period
|
||||||
|
from `tabGL Entry` gle
|
||||||
|
join `tabAsset` a on
|
||||||
|
gle.against_voucher = a.name
|
||||||
|
join `tabAsset Category Account` aca on
|
||||||
|
aca.parent = a.asset_category and aca.company_name = %(company)s
|
||||||
|
join `tabCompany` company on
|
||||||
|
company.name = %(company)s
|
||||||
|
where a.docstatus=1 and a.company=%(company)s and a.calculate_depreciation=0 and a.purchase_date <= %(to_date)s and gle.debit != 0 and gle.is_cancelled = 0 and gle.account = ifnull(aca.depreciation_expense_account, company.depreciation_expense_account)
|
||||||
|
group by a.asset_category
|
||||||
|
union
|
||||||
SELECT a.asset_category,
|
SELECT a.asset_category,
|
||||||
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 and (a.disposal_date < %(from_date)s or a.disposal_date > %(to_date)s) then
|
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 and (a.disposal_date < %(from_date)s or a.disposal_date > %(to_date)s) then
|
||||||
0
|
0
|
||||||
|
|||||||
@@ -1512,9 +1512,12 @@ def update_voucher_outstanding(voucher_type, voucher_no, account, party_type, pa
|
|||||||
ref_doc = frappe.get_doc(voucher_type, voucher_no)
|
ref_doc = frappe.get_doc(voucher_type, voucher_no)
|
||||||
|
|
||||||
# Didn't use db_set for optimisation purpose
|
# Didn't use db_set for optimisation purpose
|
||||||
ref_doc.outstanding_amount = outstanding["outstanding_in_account_currency"]
|
ref_doc.outstanding_amount = outstanding["outstanding_in_account_currency"] or 0.0
|
||||||
frappe.db.set_value(
|
frappe.db.set_value(
|
||||||
voucher_type, voucher_no, "outstanding_amount", outstanding["outstanding_in_account_currency"]
|
voucher_type,
|
||||||
|
voucher_no,
|
||||||
|
"outstanding_amount",
|
||||||
|
outstanding["outstanding_in_account_currency"] or 0.0,
|
||||||
)
|
)
|
||||||
|
|
||||||
ref_doc.set_status(update=True)
|
ref_doc.set_status(update=True)
|
||||||
|
|||||||
@@ -209,20 +209,19 @@ frappe.ui.form.on('Asset', {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var x_intervals = [frm.doc.purchase_date];
|
var x_intervals = [frappe.format(frm.doc.purchase_date, { fieldtype: 'Date' })];
|
||||||
var asset_values = [frm.doc.gross_purchase_amount];
|
var asset_values = [frm.doc.gross_purchase_amount];
|
||||||
var last_depreciation_date = frm.doc.purchase_date;
|
|
||||||
|
|
||||||
if(frm.doc.opening_accumulated_depreciation) {
|
|
||||||
last_depreciation_date = frappe.datetime.add_months(frm.doc.next_depreciation_date,
|
|
||||||
-1*frm.doc.frequency_of_depreciation);
|
|
||||||
|
|
||||||
x_intervals.push(last_depreciation_date);
|
|
||||||
asset_values.push(flt(frm.doc.gross_purchase_amount) -
|
|
||||||
flt(frm.doc.opening_accumulated_depreciation));
|
|
||||||
}
|
|
||||||
if(frm.doc.calculate_depreciation) {
|
if(frm.doc.calculate_depreciation) {
|
||||||
if (frm.doc.finance_books.length == 1) {
|
if(frm.doc.opening_accumulated_depreciation) {
|
||||||
|
var depreciation_date = frappe.datetime.add_months(
|
||||||
|
frm.doc.finance_books[0].depreciation_start_date,
|
||||||
|
-1 * frm.doc.finance_books[0].frequency_of_depreciation
|
||||||
|
);
|
||||||
|
x_intervals.push(frappe.format(depreciation_date, { fieldtype: 'Date' }));
|
||||||
|
asset_values.push(flt(frm.doc.gross_purchase_amount - frm.doc.opening_accumulated_depreciation, precision('gross_purchase_amount')));
|
||||||
|
}
|
||||||
|
|
||||||
let depr_schedule = (await frappe.call(
|
let depr_schedule = (await frappe.call(
|
||||||
"erpnext.assets.doctype.asset_depreciation_schedule.asset_depreciation_schedule.get_depr_schedule",
|
"erpnext.assets.doctype.asset_depreciation_schedule.asset_depreciation_schedule.get_depr_schedule",
|
||||||
{
|
{
|
||||||
@@ -233,10 +232,9 @@ frappe.ui.form.on('Asset', {
|
|||||||
)).message;
|
)).message;
|
||||||
|
|
||||||
$.each(depr_schedule || [], function(i, v) {
|
$.each(depr_schedule || [], function(i, v) {
|
||||||
x_intervals.push(v.schedule_date);
|
x_intervals.push(frappe.format(v.schedule_date, { fieldtype: 'Date' }));
|
||||||
var asset_value = flt(frm.doc.gross_purchase_amount) - flt(v.accumulated_depreciation_amount);
|
var asset_value = flt(frm.doc.gross_purchase_amount - v.accumulated_depreciation_amount, precision('gross_purchase_amount'));
|
||||||
if(v.journal_entry) {
|
if(v.journal_entry) {
|
||||||
last_depreciation_date = v.schedule_date;
|
|
||||||
asset_values.push(asset_value);
|
asset_values.push(asset_value);
|
||||||
} else {
|
} else {
|
||||||
if (in_list(["Scrapped", "Sold"], frm.doc.status)) {
|
if (in_list(["Scrapped", "Sold"], frm.doc.status)) {
|
||||||
@@ -246,25 +244,27 @@ frappe.ui.form.on('Asset', {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
|
if(frm.doc.opening_accumulated_depreciation) {
|
||||||
|
x_intervals.push(frappe.format(frm.doc.creation.split(" ")[0], { fieldtype: 'Date' }));
|
||||||
|
asset_values.push(flt(frm.doc.gross_purchase_amount - frm.doc.opening_accumulated_depreciation, precision('gross_purchase_amount')));
|
||||||
|
}
|
||||||
|
|
||||||
let depr_entries = (await frappe.call({
|
let depr_entries = (await frappe.call({
|
||||||
method: "get_manual_depreciation_entries",
|
method: "get_manual_depreciation_entries",
|
||||||
doc: frm.doc,
|
doc: frm.doc,
|
||||||
})).message;
|
})).message;
|
||||||
|
|
||||||
$.each(depr_entries || [], function(i, v) {
|
$.each(depr_entries || [], function(i, v) {
|
||||||
x_intervals.push(v.posting_date);
|
x_intervals.push(frappe.format(v.posting_date, { fieldtype: 'Date' }));
|
||||||
last_depreciation_date = v.posting_date;
|
|
||||||
let last_asset_value = asset_values[asset_values.length - 1]
|
let last_asset_value = asset_values[asset_values.length - 1]
|
||||||
asset_values.push(last_asset_value - v.value);
|
asset_values.push(last_asset_value - v.value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if(in_list(["Scrapped", "Sold"], frm.doc.status)) {
|
if(in_list(["Scrapped", "Sold"], frm.doc.status)) {
|
||||||
x_intervals.push(frm.doc.disposal_date);
|
x_intervals.push(frappe.format(frm.doc.disposal_date, { fieldtype: 'Date' }));
|
||||||
asset_values.push(0);
|
asset_values.push(0);
|
||||||
last_depreciation_date = frm.doc.disposal_date;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
frm.dashboard.render_graph({
|
frm.dashboard.render_graph({
|
||||||
|
|||||||
@@ -429,25 +429,16 @@ class Asset(AccountsController):
|
|||||||
|
|
||||||
def get_value_after_depreciation(self, finance_book=None):
|
def get_value_after_depreciation(self, finance_book=None):
|
||||||
if not self.calculate_depreciation:
|
if not self.calculate_depreciation:
|
||||||
return self.value_after_depreciation
|
return flt(self.value_after_depreciation, self.precision("gross_purchase_amount"))
|
||||||
|
|
||||||
if not finance_book:
|
if not finance_book:
|
||||||
return self.get("finance_books")[0].value_after_depreciation
|
return flt(
|
||||||
|
self.get("finance_books")[0].value_after_depreciation, self.precision("gross_purchase_amount")
|
||||||
|
)
|
||||||
|
|
||||||
for row in self.get("finance_books"):
|
for row in self.get("finance_books"):
|
||||||
if finance_book == row.finance_book:
|
if finance_book == row.finance_book:
|
||||||
return row.value_after_depreciation
|
return flt(row.value_after_depreciation, self.precision("gross_purchase_amount"))
|
||||||
|
|
||||||
def _get_value_after_depreciation_for_making_schedule(self, fb_row):
|
|
||||||
# value_after_depreciation - current Asset value
|
|
||||||
if self.docstatus == 1 and fb_row.value_after_depreciation:
|
|
||||||
value_after_depreciation = flt(fb_row.value_after_depreciation)
|
|
||||||
else:
|
|
||||||
value_after_depreciation = flt(self.gross_purchase_amount) - flt(
|
|
||||||
self.opening_accumulated_depreciation
|
|
||||||
)
|
|
||||||
|
|
||||||
return value_after_depreciation
|
|
||||||
|
|
||||||
def get_default_finance_book_idx(self):
|
def get_default_finance_book_idx(self):
|
||||||
if not self.get("default_finance_book") and self.company:
|
if not self.get("default_finance_book") and self.company:
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ class AssetDepreciationSchedule(Document):
|
|||||||
):
|
):
|
||||||
asset_doc.validate_asset_finance_books(row)
|
asset_doc.validate_asset_finance_books(row)
|
||||||
|
|
||||||
value_after_depreciation = asset_doc._get_value_after_depreciation_for_making_schedule(row)
|
value_after_depreciation = _get_value_after_depreciation_for_making_schedule(asset_doc, row)
|
||||||
row.value_after_depreciation = value_after_depreciation
|
row.value_after_depreciation = value_after_depreciation
|
||||||
|
|
||||||
if update_asset_finance_book_row:
|
if update_asset_finance_book_row:
|
||||||
@@ -325,6 +325,17 @@ class AssetDepreciationSchedule(Document):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_value_after_depreciation_for_making_schedule(asset_doc, fb_row):
|
||||||
|
if asset_doc.docstatus == 1 and fb_row.value_after_depreciation:
|
||||||
|
value_after_depreciation = flt(fb_row.value_after_depreciation)
|
||||||
|
else:
|
||||||
|
value_after_depreciation = flt(asset_doc.gross_purchase_amount) - flt(
|
||||||
|
asset_doc.opening_accumulated_depreciation
|
||||||
|
)
|
||||||
|
|
||||||
|
return value_after_depreciation
|
||||||
|
|
||||||
|
|
||||||
def make_draft_asset_depr_schedules_if_not_present(asset_doc):
|
def make_draft_asset_depr_schedules_if_not_present(asset_doc):
|
||||||
for row in asset_doc.get("finance_books"):
|
for row in asset_doc.get("finance_books"):
|
||||||
draft_asset_depr_schedule_name = get_asset_depr_schedule_name(
|
draft_asset_depr_schedule_name = get_asset_depr_schedule_name(
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.query_builder.functions import Sum
|
from frappe.query_builder.functions import Sum
|
||||||
from frappe.utils import cstr, formatdate, getdate
|
from frappe.utils import cstr, flt, formatdate, getdate
|
||||||
|
|
||||||
from erpnext.accounts.report.financial_statements import (
|
from erpnext.accounts.report.financial_statements import (
|
||||||
get_fiscal_year_data,
|
get_fiscal_year_data,
|
||||||
@@ -102,13 +102,9 @@ def get_data(filters):
|
|||||||
]
|
]
|
||||||
assets_record = frappe.db.get_all("Asset", filters=conditions, fields=fields)
|
assets_record = frappe.db.get_all("Asset", filters=conditions, fields=fields)
|
||||||
|
|
||||||
finance_book_filter = ("is", "not set")
|
|
||||||
if filters.finance_book:
|
|
||||||
finance_book_filter = ("=", filters.finance_book)
|
|
||||||
|
|
||||||
assets_linked_to_fb = frappe.db.get_all(
|
assets_linked_to_fb = frappe.db.get_all(
|
||||||
doctype="Asset Finance Book",
|
doctype="Asset Finance Book",
|
||||||
filters={"finance_book": finance_book_filter},
|
filters={"finance_book": filters.finance_book or ("is", "not set")},
|
||||||
pluck="parent",
|
pluck="parent",
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -194,7 +190,7 @@ def get_depreciation_amount_of_asset(asset, depreciation_amount_map, filters):
|
|||||||
else:
|
else:
|
||||||
depr_amount = get_manual_depreciation_amount_of_asset(asset, filters)
|
depr_amount = get_manual_depreciation_amount_of_asset(asset, filters)
|
||||||
|
|
||||||
return depr_amount
|
return flt(depr_amount, 2)
|
||||||
|
|
||||||
|
|
||||||
def get_finance_book_value_map(filters):
|
def get_finance_book_value_map(filters):
|
||||||
|
|||||||
@@ -124,12 +124,11 @@ frappe.ui.form.on("Request for Quotation",{
|
|||||||
frappe.urllib.get_full_url(
|
frappe.urllib.get_full_url(
|
||||||
"/api/method/erpnext.buying.doctype.request_for_quotation.request_for_quotation.get_pdf?" +
|
"/api/method/erpnext.buying.doctype.request_for_quotation.request_for_quotation.get_pdf?" +
|
||||||
new URLSearchParams({
|
new URLSearchParams({
|
||||||
doctype: frm.doc.doctype,
|
|
||||||
name: frm.doc.name,
|
name: frm.doc.name,
|
||||||
supplier: data.supplier,
|
supplier: data.supplier,
|
||||||
print_format: data.print_format || "Standard",
|
print_format: data.print_format || "Standard",
|
||||||
language: data.language || frappe.boot.lang,
|
language: data.language || frappe.boot.lang,
|
||||||
letter_head: data.letter_head || frm.doc.letter_head || "",
|
letterhead: data.letter_head || frm.doc.letter_head || "",
|
||||||
}).toString()
|
}).toString()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
@@ -388,26 +389,28 @@ def create_rfq_items(sq_doc, supplier, data):
|
|||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_pdf(doctype, name, supplier, print_format=None, language=None, letter_head=None):
|
def get_pdf(
|
||||||
|
name: str,
|
||||||
|
supplier: str,
|
||||||
|
print_format: Optional[str] = None,
|
||||||
|
language: Optional[str] = None,
|
||||||
|
letterhead: Optional[str] = None,
|
||||||
|
):
|
||||||
|
doc = frappe.get_doc("Request for Quotation", name)
|
||||||
|
if supplier:
|
||||||
|
doc.update_supplier_part_no(supplier)
|
||||||
|
|
||||||
# permissions get checked in `download_pdf`
|
# permissions get checked in `download_pdf`
|
||||||
if doc := get_rfq_doc(doctype, name, supplier):
|
|
||||||
download_pdf(
|
download_pdf(
|
||||||
doctype,
|
doc.doctype,
|
||||||
name,
|
doc.name,
|
||||||
print_format,
|
print_format,
|
||||||
doc=doc,
|
doc=doc,
|
||||||
language=language,
|
language=language,
|
||||||
letter_head=letter_head or None,
|
letterhead=letterhead or None,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_rfq_doc(doctype, name, supplier):
|
|
||||||
if supplier:
|
|
||||||
doc = frappe.get_doc(doctype, name)
|
|
||||||
doc.update_supplier_part_no(supplier)
|
|
||||||
return doc
|
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_item_from_material_requests_based_on_supplier(source_name, target_doc=None):
|
def get_item_from_material_requests_based_on_supplier(source_name, target_doc=None):
|
||||||
mr_items_list = frappe.db.sql(
|
mr_items_list = frappe.db.sql(
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ from frappe.utils import nowdate
|
|||||||
|
|
||||||
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import (
|
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import (
|
||||||
create_supplier_quotation,
|
create_supplier_quotation,
|
||||||
|
get_pdf,
|
||||||
make_supplier_quotation_from_rfq,
|
make_supplier_quotation_from_rfq,
|
||||||
)
|
)
|
||||||
from erpnext.crm.doctype.opportunity.opportunity import make_request_for_quotation as make_rfq
|
from erpnext.crm.doctype.opportunity.opportunity import make_request_for_quotation as make_rfq
|
||||||
@@ -124,6 +125,11 @@ class TestRequestforQuotation(FrappeTestCase):
|
|||||||
rfq.status = "Draft"
|
rfq.status = "Draft"
|
||||||
rfq.submit()
|
rfq.submit()
|
||||||
|
|
||||||
|
def test_get_pdf(self):
|
||||||
|
rfq = make_request_for_quotation()
|
||||||
|
get_pdf(rfq.name, rfq.get("suppliers")[0].supplier)
|
||||||
|
self.assertEqual(frappe.local.response.type, "pdf")
|
||||||
|
|
||||||
|
|
||||||
def make_request_for_quotation(**args):
|
def make_request_for_quotation(**args):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -252,6 +252,7 @@ def get_already_returned_items(doc):
|
|||||||
child.parent = par.name and par.docstatus = 1
|
child.parent = par.name and par.docstatus = 1
|
||||||
and par.is_return = 1 and par.return_against = %s
|
and par.is_return = 1 and par.return_against = %s
|
||||||
group by item_code
|
group by item_code
|
||||||
|
for update
|
||||||
""".format(
|
""".format(
|
||||||
column, doc.doctype, doc.doctype
|
column, doc.doctype, doc.doctype
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -26,10 +26,11 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-02-08 12:51:48.971517",
|
"modified": "2023-02-10 00:51:44.973957",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "CRM",
|
"module": "CRM",
|
||||||
"name": "Lead Source",
|
"name": "Lead Source",
|
||||||
|
"naming_rule": "By fieldname",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
@@ -58,5 +59,7 @@
|
|||||||
],
|
],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC"
|
"sort_order": "DESC",
|
||||||
|
"states": [],
|
||||||
|
"translated_doctype": 1
|
||||||
}
|
}
|
||||||
@@ -18,10 +18,11 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-05-20 12:22:01.866472",
|
"modified": "2023-02-10 01:40:23.713390",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "CRM",
|
"module": "CRM",
|
||||||
"name": "Sales Stage",
|
"name": "Sales Stage",
|
||||||
|
"naming_rule": "By fieldname",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
@@ -40,5 +41,7 @@
|
|||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"track_changes": 1
|
"states": [],
|
||||||
|
"track_changes": 1,
|
||||||
|
"translated_doctype": 1
|
||||||
}
|
}
|
||||||
@@ -289,7 +289,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "scrap_items",
|
"fieldname": "scrap_items",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"label": "Items",
|
"label": "Scrap Items",
|
||||||
"options": "BOM Scrap Item"
|
"options": "BOM Scrap Item"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -605,7 +605,7 @@
|
|||||||
"image_field": "image",
|
"image_field": "image",
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-01-10 07:47:08.652616",
|
"modified": "2023-02-13 17:31:37.504565",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Manufacturing",
|
"module": "Manufacturing",
|
||||||
"name": "BOM",
|
"name": "BOM",
|
||||||
|
|||||||
@@ -1,16 +1,17 @@
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
|
||||||
|
|
||||||
|
|
||||||
def execute():
|
def execute():
|
||||||
from erpnext.setup.setup_wizard.operations.install_fixtures import default_sales_partner_type
|
from erpnext.setup.setup_wizard.operations.install_fixtures import read_lines
|
||||||
|
|
||||||
frappe.reload_doc("selling", "doctype", "sales_partner_type")
|
frappe.reload_doc("selling", "doctype", "sales_partner_type")
|
||||||
|
|
||||||
frappe.local.lang = frappe.db.get_default("lang") or "en"
|
frappe.local.lang = frappe.db.get_default("lang") or "en"
|
||||||
|
|
||||||
|
default_sales_partner_type = read_lines("sales_partner_type.txt")
|
||||||
|
|
||||||
for s in default_sales_partner_type:
|
for s in default_sales_partner_type:
|
||||||
insert_sales_partner_type(_(s))
|
insert_sales_partner_type(s)
|
||||||
|
|
||||||
# get partner type in existing forms (customized)
|
# get partner type in existing forms (customized)
|
||||||
# and create a document if not created
|
# and create a document if not created
|
||||||
|
|||||||
@@ -408,7 +408,7 @@
|
|||||||
"depends_on": "eval:(doc.frequency == \"Daily\" && doc.collect_progress == true)",
|
"depends_on": "eval:(doc.frequency == \"Daily\" && doc.collect_progress == true)",
|
||||||
"fieldname": "daily_time_to_send",
|
"fieldname": "daily_time_to_send",
|
||||||
"fieldtype": "Time",
|
"fieldtype": "Time",
|
||||||
"label": "Time to send"
|
"label": "Daily Time to send"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:(doc.frequency == \"Weekly\" && doc.collect_progress == true)",
|
"depends_on": "eval:(doc.frequency == \"Weekly\" && doc.collect_progress == true)",
|
||||||
@@ -421,7 +421,7 @@
|
|||||||
"depends_on": "eval:(doc.frequency == \"Weekly\" && doc.collect_progress == true)",
|
"depends_on": "eval:(doc.frequency == \"Weekly\" && doc.collect_progress == true)",
|
||||||
"fieldname": "weekly_time_to_send",
|
"fieldname": "weekly_time_to_send",
|
||||||
"fieldtype": "Time",
|
"fieldtype": "Time",
|
||||||
"label": "Time to send"
|
"label": "Weekly Time to send"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_45",
|
"fieldname": "column_break_45",
|
||||||
@@ -451,7 +451,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"max_attachments": 4,
|
"max_attachments": 4,
|
||||||
"modified": "2022-06-23 16:45:06.108499",
|
"modified": "2023-02-14 04:54:25.819620",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Projects",
|
"module": "Projects",
|
||||||
"name": "Project",
|
"name": "Project",
|
||||||
|
|||||||
@@ -282,21 +282,21 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "base_total_costing_amount",
|
"fieldname": "base_total_costing_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Total Costing Amount",
|
"label": "Base Total Costing Amount",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "base_total_billable_amount",
|
"fieldname": "base_total_billable_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Total Billable Amount",
|
"label": "Base Total Billable Amount",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "base_total_billed_amount",
|
"fieldname": "base_total_billed_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Total Billed Amount",
|
"label": "Base Total Billed Amount",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
@@ -311,10 +311,11 @@
|
|||||||
"idx": 1,
|
"idx": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-06-15 22:08:53.930200",
|
"modified": "2023-02-14 04:55:41.735991",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Projects",
|
"module": "Projects",
|
||||||
"name": "Timesheet",
|
"name": "Timesheet",
|
||||||
|
"naming_rule": "By \"Naming Series\" field",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
@@ -388,5 +389,6 @@
|
|||||||
],
|
],
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "ASC",
|
"sort_order": "ASC",
|
||||||
|
"states": [],
|
||||||
"title_field": "title"
|
"title_field": "title"
|
||||||
}
|
}
|
||||||
@@ -1,123 +1,68 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"actions": [],
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
"allow_rename": 1,
|
"allow_rename": 1,
|
||||||
"autoname": "field:industry",
|
"autoname": "field:industry",
|
||||||
"beta": 0,
|
|
||||||
"creation": "2012-03-27 14:36:09",
|
"creation": "2012-03-27 14:36:09",
|
||||||
"custom": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "Setup",
|
"document_type": "Setup",
|
||||||
"editable_grid": 0,
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"industry"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"fieldname": "industry",
|
"fieldname": "industry",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
"in_list_view": 1,
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"label": "Industry",
|
"label": "Industry",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"oldfieldname": "industry",
|
"oldfieldname": "industry",
|
||||||
"oldfieldtype": "Data",
|
"oldfieldtype": "Data",
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 0,
|
"unique": 1
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"hide_heading": 0,
|
|
||||||
"hide_toolbar": 0,
|
|
||||||
"icon": "fa fa-flag",
|
"icon": "fa fa-flag",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"image_view": 0,
|
"links": [],
|
||||||
"in_create": 0,
|
"modified": "2023-02-10 03:14:40.735763",
|
||||||
|
|
||||||
"is_submittable": 0,
|
|
||||||
"issingle": 0,
|
|
||||||
"istable": 0,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2020-09-18 17:26:09.703215",
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Selling",
|
"module": "Selling",
|
||||||
"name": "Industry Type",
|
"name": "Industry Type",
|
||||||
|
"naming_rule": "By fieldname",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 0,
|
|
||||||
"apply_user_permissions": 0,
|
|
||||||
"cancel": 0,
|
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 0,
|
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 0,
|
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "Sales Manager",
|
"role": "Sales Manager",
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
|
||||||
"apply_user_permissions": 0,
|
|
||||||
"cancel": 0,
|
|
||||||
"create": 0,
|
|
||||||
"delete": 0,
|
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 0,
|
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "Sales User",
|
"role": "Sales User"
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 0,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
|
||||||
"apply_user_permissions": 0,
|
|
||||||
"cancel": 0,
|
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 0,
|
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 0,
|
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "Sales Master Manager",
|
"role": "Sales Master Manager",
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"read_only": 0,
|
"sort_field": "modified",
|
||||||
"read_only_onload": 0,
|
"sort_order": "DESC",
|
||||||
"track_seen": 0
|
"states": [],
|
||||||
|
"translated_doctype": 1
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"actions": [],
|
"actions": [],
|
||||||
|
"allow_import": 1,
|
||||||
"creation": "2021-08-27 19:28:07.559978",
|
"creation": "2021-08-27 19:28:07.559978",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
@@ -51,7 +52,7 @@
|
|||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-09-14 13:27:58.612334",
|
"modified": "2023-02-15 13:00:50.379713",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Selling",
|
"module": "Selling",
|
||||||
"name": "Party Specific Item",
|
"name": "Party Specific Item",
|
||||||
@@ -72,6 +73,7 @@
|
|||||||
],
|
],
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
|
"states": [],
|
||||||
"title_field": "party",
|
"title_field": "party",
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
}
|
}
|
||||||
@@ -85,11 +85,15 @@ erpnext.selling.QuotationController = class QuotationController extends erpnext.
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (doc.docstatus == 1 && !["Lost", "Ordered"].includes(doc.status)) {
|
if (doc.docstatus == 1 && !["Lost", "Ordered"].includes(doc.status)) {
|
||||||
|
if (frappe.boot.sysdefaults.allow_sales_order_creation_for_expired_quotation
|
||||||
|
|| (!doc.valid_till)
|
||||||
|
|| frappe.datetime.get_diff(doc.valid_till, frappe.datetime.get_today()) >= 0) {
|
||||||
this.frm.add_custom_button(
|
this.frm.add_custom_button(
|
||||||
__("Sales Order"),
|
__("Sales Order"),
|
||||||
this.frm.cscript["Make Sales Order"],
|
this.frm.cscript["Make Sales Order"],
|
||||||
__("Create")
|
__("Create")
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if(doc.status!=="Ordered") {
|
if(doc.status!=="Ordered") {
|
||||||
this.frm.add_custom_button(__('Set as Lost'), () => {
|
this.frm.add_custom_button(__('Set as Lost'), () => {
|
||||||
|
|||||||
@@ -195,6 +195,17 @@ def get_list_context(context=None):
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def make_sales_order(source_name: str, target_doc=None):
|
def make_sales_order(source_name: str, target_doc=None):
|
||||||
|
if not frappe.db.get_singles_value(
|
||||||
|
"Selling Settings", "allow_sales_order_creation_for_expired_quotation"
|
||||||
|
):
|
||||||
|
quotation = frappe.db.get_value(
|
||||||
|
"Quotation", source_name, ["transaction_date", "valid_till"], as_dict=1
|
||||||
|
)
|
||||||
|
if quotation.valid_till and (
|
||||||
|
quotation.valid_till < quotation.transaction_date or quotation.valid_till < getdate(nowdate())
|
||||||
|
):
|
||||||
|
frappe.throw(_("Validity period of this quotation has ended."))
|
||||||
|
|
||||||
return _make_sales_order(source_name, target_doc)
|
return _make_sales_order(source_name, target_doc)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -144,11 +144,21 @@ class TestQuotation(FrappeTestCase):
|
|||||||
def test_so_from_expired_quotation(self):
|
def test_so_from_expired_quotation(self):
|
||||||
from erpnext.selling.doctype.quotation.quotation import make_sales_order
|
from erpnext.selling.doctype.quotation.quotation import make_sales_order
|
||||||
|
|
||||||
|
frappe.db.set_single_value(
|
||||||
|
"Selling Settings", "allow_sales_order_creation_for_expired_quotation", 0
|
||||||
|
)
|
||||||
|
|
||||||
quotation = frappe.copy_doc(test_records[0])
|
quotation = frappe.copy_doc(test_records[0])
|
||||||
quotation.valid_till = add_days(nowdate(), -1)
|
quotation.valid_till = add_days(nowdate(), -1)
|
||||||
quotation.insert()
|
quotation.insert()
|
||||||
quotation.submit()
|
quotation.submit()
|
||||||
|
|
||||||
|
self.assertRaises(frappe.ValidationError, make_sales_order, quotation.name)
|
||||||
|
|
||||||
|
frappe.db.set_single_value(
|
||||||
|
"Selling Settings", "allow_sales_order_creation_for_expired_quotation", 1
|
||||||
|
)
|
||||||
|
|
||||||
make_sales_order(quotation.name)
|
make_sales_order(quotation.name)
|
||||||
|
|
||||||
def test_shopping_cart_without_website_item(self):
|
def test_shopping_cart_without_website_item(self):
|
||||||
|
|||||||
@@ -1,94 +1,47 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"actions": [],
|
||||||
"allow_guest_to_view": 0,
|
|
||||||
"allow_import": 0,
|
|
||||||
"allow_rename": 0,
|
|
||||||
"autoname": "field:sales_partner_type",
|
"autoname": "field:sales_partner_type",
|
||||||
"beta": 0,
|
|
||||||
"creation": "2018-06-11 13:15:57.404716",
|
"creation": "2018-06-11 13:15:57.404716",
|
||||||
"custom": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "",
|
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"sales_partner_type"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "sales_partner_type",
|
"fieldname": "sales_partner_type",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Sales Partner Type",
|
"label": "Sales Partner Type",
|
||||||
"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,
|
"reqd": 1,
|
||||||
"search_index": 0,
|
"unique": 1
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"links": [],
|
||||||
"hide_heading": 0,
|
"modified": "2023-02-10 01:00:20.110800",
|
||||||
"hide_toolbar": 0,
|
|
||||||
"idx": 0,
|
|
||||||
"image_view": 0,
|
|
||||||
"in_create": 0,
|
|
||||||
"is_submittable": 0,
|
|
||||||
"issingle": 0,
|
|
||||||
"istable": 0,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2018-06-11 13:45:13.554307",
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Selling",
|
"module": "Selling",
|
||||||
"name": "Sales Partner Type",
|
"name": "Sales Partner Type",
|
||||||
"name_case": "",
|
"naming_rule": "By fieldname",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 0,
|
|
||||||
"cancel": 0,
|
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 1,
|
"export": 1,
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "System Manager",
|
"role": "System Manager",
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 0,
|
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"track_changes": 0,
|
"states": [],
|
||||||
"track_seen": 0
|
"translated_doctype": 1
|
||||||
}
|
}
|
||||||
@@ -27,6 +27,7 @@
|
|||||||
"column_break_5",
|
"column_break_5",
|
||||||
"allow_multiple_items",
|
"allow_multiple_items",
|
||||||
"allow_against_multiple_purchase_orders",
|
"allow_against_multiple_purchase_orders",
|
||||||
|
"allow_sales_order_creation_for_expired_quotation",
|
||||||
"hide_tax_id",
|
"hide_tax_id",
|
||||||
"enable_discount_accounting"
|
"enable_discount_accounting"
|
||||||
],
|
],
|
||||||
@@ -172,6 +173,12 @@
|
|||||||
"fieldname": "enable_discount_accounting",
|
"fieldname": "enable_discount_accounting",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Enable Discount Accounting for Selling"
|
"label": "Enable Discount Accounting for Selling"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "allow_sales_order_creation_for_expired_quotation",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Allow Sales Order Creation For Expired Quotation"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-cog",
|
"icon": "fa fa-cog",
|
||||||
@@ -179,7 +186,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-05-31 19:39:48.398738",
|
"modified": "2023-02-04 12:37:53.380857",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Selling",
|
"module": "Selling",
|
||||||
"name": "Selling Settings",
|
"name": "Selling Settings",
|
||||||
|
|||||||
@@ -103,6 +103,11 @@ function get_filters() {
|
|||||||
return options
|
return options
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"only_immediate_upcoming_term",
|
||||||
|
"label": __("Show only the Immediate Upcoming Term"),
|
||||||
|
"fieldtype": "Check",
|
||||||
|
},
|
||||||
]
|
]
|
||||||
return filters;
|
return filters;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import _, qb, query_builder
|
from frappe import _, qb, query_builder
|
||||||
from frappe.query_builder import Criterion, functions
|
from frappe.query_builder import Criterion, functions
|
||||||
|
from frappe.utils.dateutils import getdate
|
||||||
|
|
||||||
|
|
||||||
def get_columns():
|
def get_columns():
|
||||||
@@ -208,6 +209,7 @@ def get_so_with_invoices(filters):
|
|||||||
)
|
)
|
||||||
.where(
|
.where(
|
||||||
(so.docstatus == 1)
|
(so.docstatus == 1)
|
||||||
|
& (so.status.isin(["To Deliver and Bill", "To Bill"]))
|
||||||
& (so.payment_terms_template != "NULL")
|
& (so.payment_terms_template != "NULL")
|
||||||
& (so.company == conditions.company)
|
& (so.company == conditions.company)
|
||||||
& (so.transaction_date[conditions.start_date : conditions.end_date])
|
& (so.transaction_date[conditions.start_date : conditions.end_date])
|
||||||
@@ -291,6 +293,18 @@ def filter_on_calculated_status(filters, sales_orders):
|
|||||||
return sales_orders
|
return sales_orders
|
||||||
|
|
||||||
|
|
||||||
|
def filter_for_immediate_upcoming_term(filters, sales_orders):
|
||||||
|
if filters.only_immediate_upcoming_term and sales_orders:
|
||||||
|
immediate_term_found = set()
|
||||||
|
filtered_data = []
|
||||||
|
for order in sales_orders:
|
||||||
|
if order.name not in immediate_term_found and order.due_date > getdate():
|
||||||
|
filtered_data.append(order)
|
||||||
|
immediate_term_found.add(order.name)
|
||||||
|
return filtered_data
|
||||||
|
return sales_orders
|
||||||
|
|
||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
columns = get_columns()
|
columns = get_columns()
|
||||||
sales_orders, so_invoices = get_so_with_invoices(filters)
|
sales_orders, so_invoices = get_so_with_invoices(filters)
|
||||||
@@ -298,6 +312,8 @@ def execute(filters=None):
|
|||||||
|
|
||||||
sales_orders = filter_on_calculated_status(filters, sales_orders)
|
sales_orders = filter_on_calculated_status(filters, sales_orders)
|
||||||
|
|
||||||
|
sales_orders = filter_for_immediate_upcoming_term(filters, sales_orders)
|
||||||
|
|
||||||
prepare_chart(sales_orders)
|
prepare_chart(sales_orders)
|
||||||
|
|
||||||
data = sales_orders
|
data = sales_orders
|
||||||
|
|||||||
@@ -175,7 +175,9 @@ def prepare_data(data, so_elapsed_time, filters):
|
|||||||
# update existing entry
|
# update existing entry
|
||||||
so_row = sales_order_map[so_name]
|
so_row = sales_order_map[so_name]
|
||||||
so_row["required_date"] = max(getdate(so_row["delivery_date"]), getdate(row["delivery_date"]))
|
so_row["required_date"] = max(getdate(so_row["delivery_date"]), getdate(row["delivery_date"]))
|
||||||
so_row["delay"] = min(so_row["delay"], row["delay"])
|
so_row["delay"] = (
|
||||||
|
min(so_row["delay"], row["delay"]) if row["delay"] and so_row["delay"] else so_row["delay"]
|
||||||
|
)
|
||||||
|
|
||||||
# sum numeric columns
|
# sum numeric columns
|
||||||
fields = [
|
fields = [
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
"icon": "fa fa-bookmark",
|
"icon": "fa fa-bookmark",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-06-28 17:10:26.853753",
|
"modified": "2023-02-10 01:53:41.319386",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Setup",
|
"module": "Setup",
|
||||||
"name": "Designation",
|
"name": "Designation",
|
||||||
@@ -58,5 +58,6 @@
|
|||||||
"show_name_in_global_search": 1,
|
"show_name_in_global_search": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "ASC",
|
"sort_order": "ASC",
|
||||||
"states": []
|
"states": [],
|
||||||
|
"translated_doctype": 1
|
||||||
}
|
}
|
||||||
31
erpnext/setup/setup_wizard/data/designation.txt
Normal file
31
erpnext/setup/setup_wizard/data/designation.txt
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
Accountant
|
||||||
|
Administrative Assistant
|
||||||
|
Administrative Officer
|
||||||
|
Analyst
|
||||||
|
Associate
|
||||||
|
Business Analyst
|
||||||
|
Business Development Manager
|
||||||
|
Consultant
|
||||||
|
Chief Executive Officer
|
||||||
|
Chief Financial Officer
|
||||||
|
Chief Operating Officer
|
||||||
|
Chief Technology Officer
|
||||||
|
Customer Service Representative
|
||||||
|
Designer
|
||||||
|
Engineer
|
||||||
|
Executive Assistant
|
||||||
|
Finance Manager
|
||||||
|
HR Manager
|
||||||
|
Head of Marketing and Sales
|
||||||
|
Manager
|
||||||
|
Managing Director
|
||||||
|
Marketing Manager
|
||||||
|
Marketing Specialist
|
||||||
|
President
|
||||||
|
Product Manager
|
||||||
|
Project Manager
|
||||||
|
Researcher
|
||||||
|
Sales Representative
|
||||||
|
Secretary
|
||||||
|
Software Developer
|
||||||
|
Vice President
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
from frappe import _
|
|
||||||
|
|
||||||
|
|
||||||
def get_industry_types():
|
|
||||||
return [
|
|
||||||
_("Accounting"),
|
|
||||||
_("Advertising"),
|
|
||||||
_("Aerospace"),
|
|
||||||
_("Agriculture"),
|
|
||||||
_("Airline"),
|
|
||||||
_("Apparel & Accessories"),
|
|
||||||
_("Automotive"),
|
|
||||||
_("Banking"),
|
|
||||||
_("Biotechnology"),
|
|
||||||
_("Broadcasting"),
|
|
||||||
_("Brokerage"),
|
|
||||||
_("Chemical"),
|
|
||||||
_("Computer"),
|
|
||||||
_("Consulting"),
|
|
||||||
_("Consumer Products"),
|
|
||||||
_("Cosmetics"),
|
|
||||||
_("Defense"),
|
|
||||||
_("Department Stores"),
|
|
||||||
_("Education"),
|
|
||||||
_("Electronics"),
|
|
||||||
_("Energy"),
|
|
||||||
_("Entertainment & Leisure"),
|
|
||||||
_("Executive Search"),
|
|
||||||
_("Financial Services"),
|
|
||||||
_("Food, Beverage & Tobacco"),
|
|
||||||
_("Grocery"),
|
|
||||||
_("Health Care"),
|
|
||||||
_("Internet Publishing"),
|
|
||||||
_("Investment Banking"),
|
|
||||||
_("Legal"),
|
|
||||||
_("Manufacturing"),
|
|
||||||
_("Motion Picture & Video"),
|
|
||||||
_("Music"),
|
|
||||||
_("Newspaper Publishers"),
|
|
||||||
_("Online Auctions"),
|
|
||||||
_("Pension Funds"),
|
|
||||||
_("Pharmaceuticals"),
|
|
||||||
_("Private Equity"),
|
|
||||||
_("Publishing"),
|
|
||||||
_("Real Estate"),
|
|
||||||
_("Retail & Wholesale"),
|
|
||||||
_("Securities & Commodity Exchanges"),
|
|
||||||
_("Service"),
|
|
||||||
_("Soap & Detergent"),
|
|
||||||
_("Software"),
|
|
||||||
_("Sports"),
|
|
||||||
_("Technology"),
|
|
||||||
_("Telecommunications"),
|
|
||||||
_("Television"),
|
|
||||||
_("Transportation"),
|
|
||||||
_("Venture Capital"),
|
|
||||||
]
|
|
||||||
51
erpnext/setup/setup_wizard/data/industry_type.txt
Normal file
51
erpnext/setup/setup_wizard/data/industry_type.txt
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
Accounting
|
||||||
|
Advertising
|
||||||
|
Aerospace
|
||||||
|
Agriculture
|
||||||
|
Airline
|
||||||
|
Apparel & Accessories
|
||||||
|
Automotive
|
||||||
|
Banking
|
||||||
|
Biotechnology
|
||||||
|
Broadcasting
|
||||||
|
Brokerage
|
||||||
|
Chemical
|
||||||
|
Computer
|
||||||
|
Consulting
|
||||||
|
Consumer Products
|
||||||
|
Cosmetics
|
||||||
|
Defense
|
||||||
|
Department Stores
|
||||||
|
Education
|
||||||
|
Electronics
|
||||||
|
Energy
|
||||||
|
Entertainment & Leisure
|
||||||
|
Executive Search
|
||||||
|
Financial Services
|
||||||
|
Food, Beverage & Tobacco
|
||||||
|
Grocery
|
||||||
|
Health Care
|
||||||
|
Internet Publishing
|
||||||
|
Investment Banking
|
||||||
|
Legal
|
||||||
|
Manufacturing
|
||||||
|
Motion Picture & Video
|
||||||
|
Music
|
||||||
|
Newspaper Publishers
|
||||||
|
Online Auctions
|
||||||
|
Pension Funds
|
||||||
|
Pharmaceuticals
|
||||||
|
Private Equity
|
||||||
|
Publishing
|
||||||
|
Real Estate
|
||||||
|
Retail & Wholesale
|
||||||
|
Securities & Commodity Exchanges
|
||||||
|
Service
|
||||||
|
Soap & Detergent
|
||||||
|
Software
|
||||||
|
Sports
|
||||||
|
Technology
|
||||||
|
Telecommunications
|
||||||
|
Television
|
||||||
|
Transportation
|
||||||
|
Venture Capital
|
||||||
10
erpnext/setup/setup_wizard/data/lead_source.txt
Normal file
10
erpnext/setup/setup_wizard/data/lead_source.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Existing Customer
|
||||||
|
Reference
|
||||||
|
Advertisement
|
||||||
|
Cold Calling
|
||||||
|
Exhibition
|
||||||
|
Supplier Reference
|
||||||
|
Mass Mailing
|
||||||
|
Customer's Vendor
|
||||||
|
Campaign
|
||||||
|
Walk In
|
||||||
7
erpnext/setup/setup_wizard/data/sales_partner_type.txt
Normal file
7
erpnext/setup/setup_wizard/data/sales_partner_type.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Channel Partner
|
||||||
|
Distributor
|
||||||
|
Dealer
|
||||||
|
Agent
|
||||||
|
Retailer
|
||||||
|
Implementation Partner
|
||||||
|
Reseller
|
||||||
8
erpnext/setup/setup_wizard/data/sales_stage.txt
Normal file
8
erpnext/setup/setup_wizard/data/sales_stage.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Prospecting
|
||||||
|
Qualification
|
||||||
|
Needs Analysis
|
||||||
|
Value Proposition
|
||||||
|
Identifying Decision Makers
|
||||||
|
Perception Analysis
|
||||||
|
Proposal/Price Quote
|
||||||
|
Negotiation/Review
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
@@ -16,28 +17,10 @@ from frappe.utils import cstr, getdate
|
|||||||
from erpnext.accounts.doctype.account.account import RootNotEditable
|
from erpnext.accounts.doctype.account.account import RootNotEditable
|
||||||
from erpnext.regional.address_template.setup import set_up_address_templates
|
from erpnext.regional.address_template.setup import set_up_address_templates
|
||||||
|
|
||||||
default_lead_sources = [
|
|
||||||
"Existing Customer",
|
|
||||||
"Reference",
|
|
||||||
"Advertisement",
|
|
||||||
"Cold Calling",
|
|
||||||
"Exhibition",
|
|
||||||
"Supplier Reference",
|
|
||||||
"Mass Mailing",
|
|
||||||
"Customer's Vendor",
|
|
||||||
"Campaign",
|
|
||||||
"Walk In",
|
|
||||||
]
|
|
||||||
|
|
||||||
default_sales_partner_type = [
|
def read_lines(filename: str) -> list[str]:
|
||||||
"Channel Partner",
|
"""Return a list of lines from a file in the data directory."""
|
||||||
"Distributor",
|
return (Path(__file__).parent.parent / "data" / filename).read_text().splitlines()
|
||||||
"Dealer",
|
|
||||||
"Agent",
|
|
||||||
"Retailer",
|
|
||||||
"Implementation Partner",
|
|
||||||
"Reseller",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def install(country=None):
|
def install(country=None):
|
||||||
@@ -85,7 +68,11 @@ def install(country=None):
|
|||||||
# Stock Entry Type
|
# Stock Entry Type
|
||||||
{"doctype": "Stock Entry Type", "name": "Material Issue", "purpose": "Material Issue"},
|
{"doctype": "Stock Entry Type", "name": "Material Issue", "purpose": "Material Issue"},
|
||||||
{"doctype": "Stock Entry Type", "name": "Material Receipt", "purpose": "Material Receipt"},
|
{"doctype": "Stock Entry Type", "name": "Material Receipt", "purpose": "Material Receipt"},
|
||||||
{"doctype": "Stock Entry Type", "name": "Material Transfer", "purpose": "Material Transfer"},
|
{
|
||||||
|
"doctype": "Stock Entry Type",
|
||||||
|
"name": "Material Transfer",
|
||||||
|
"purpose": "Material Transfer",
|
||||||
|
},
|
||||||
{"doctype": "Stock Entry Type", "name": "Manufacture", "purpose": "Manufacture"},
|
{"doctype": "Stock Entry Type", "name": "Manufacture", "purpose": "Manufacture"},
|
||||||
{"doctype": "Stock Entry Type", "name": "Repack", "purpose": "Repack"},
|
{"doctype": "Stock Entry Type", "name": "Repack", "purpose": "Repack"},
|
||||||
{
|
{
|
||||||
@@ -103,22 +90,6 @@ def install(country=None):
|
|||||||
"name": "Material Consumption for Manufacture",
|
"name": "Material Consumption for Manufacture",
|
||||||
"purpose": "Material Consumption for Manufacture",
|
"purpose": "Material Consumption for Manufacture",
|
||||||
},
|
},
|
||||||
# Designation
|
|
||||||
{"doctype": "Designation", "designation_name": _("CEO")},
|
|
||||||
{"doctype": "Designation", "designation_name": _("Manager")},
|
|
||||||
{"doctype": "Designation", "designation_name": _("Analyst")},
|
|
||||||
{"doctype": "Designation", "designation_name": _("Engineer")},
|
|
||||||
{"doctype": "Designation", "designation_name": _("Accountant")},
|
|
||||||
{"doctype": "Designation", "designation_name": _("Secretary")},
|
|
||||||
{"doctype": "Designation", "designation_name": _("Associate")},
|
|
||||||
{"doctype": "Designation", "designation_name": _("Administrative Officer")},
|
|
||||||
{"doctype": "Designation", "designation_name": _("Business Development Manager")},
|
|
||||||
{"doctype": "Designation", "designation_name": _("HR Manager")},
|
|
||||||
{"doctype": "Designation", "designation_name": _("Project Manager")},
|
|
||||||
{"doctype": "Designation", "designation_name": _("Head of Marketing and Sales")},
|
|
||||||
{"doctype": "Designation", "designation_name": _("Software Developer")},
|
|
||||||
{"doctype": "Designation", "designation_name": _("Designer")},
|
|
||||||
{"doctype": "Designation", "designation_name": _("Researcher")},
|
|
||||||
# territory: with two default territories, one for home country and one named Rest of the World
|
# territory: with two default territories, one for home country and one named Rest of the World
|
||||||
{
|
{
|
||||||
"doctype": "Territory",
|
"doctype": "Territory",
|
||||||
@@ -291,28 +262,18 @@ def install(country=None):
|
|||||||
{"doctype": "Market Segment", "market_segment": _("Lower Income")},
|
{"doctype": "Market Segment", "market_segment": _("Lower Income")},
|
||||||
{"doctype": "Market Segment", "market_segment": _("Middle Income")},
|
{"doctype": "Market Segment", "market_segment": _("Middle Income")},
|
||||||
{"doctype": "Market Segment", "market_segment": _("Upper Income")},
|
{"doctype": "Market Segment", "market_segment": _("Upper Income")},
|
||||||
# Sales Stages
|
|
||||||
{"doctype": "Sales Stage", "stage_name": _("Prospecting")},
|
|
||||||
{"doctype": "Sales Stage", "stage_name": _("Qualification")},
|
|
||||||
{"doctype": "Sales Stage", "stage_name": _("Needs Analysis")},
|
|
||||||
{"doctype": "Sales Stage", "stage_name": _("Value Proposition")},
|
|
||||||
{"doctype": "Sales Stage", "stage_name": _("Identifying Decision Makers")},
|
|
||||||
{"doctype": "Sales Stage", "stage_name": _("Perception Analysis")},
|
|
||||||
{"doctype": "Sales Stage", "stage_name": _("Proposal/Price Quote")},
|
|
||||||
{"doctype": "Sales Stage", "stage_name": _("Negotiation/Review")},
|
|
||||||
# Warehouse Type
|
# Warehouse Type
|
||||||
{"doctype": "Warehouse Type", "name": "Transit"},
|
{"doctype": "Warehouse Type", "name": "Transit"},
|
||||||
]
|
]
|
||||||
|
|
||||||
from erpnext.setup.setup_wizard.data.industry_type import get_industry_types
|
for doctype, title_field, filename in (
|
||||||
|
("Designation", "designation_name", "designation.txt"),
|
||||||
records += [{"doctype": "Industry Type", "industry": d} for d in get_industry_types()]
|
("Sales Stage", "stage_name", "sales_stage.txt"),
|
||||||
# records += [{"doctype":"Operation", "operation": d} for d in get_operations()]
|
("Industry Type", "industry", "industry_type.txt"),
|
||||||
records += [{"doctype": "Lead Source", "source_name": _(d)} for d in default_lead_sources]
|
("Lead Source", "source_name", "lead_source.txt"),
|
||||||
|
("Sales Partner Type", "sales_partner_type", "sales_partner_type.txt"),
|
||||||
records += [
|
):
|
||||||
{"doctype": "Sales Partner Type", "sales_partner_type": _(d)} for d in default_sales_partner_type
|
records += [{"doctype": doctype, title_field: title} for title in read_lines(filename)]
|
||||||
]
|
|
||||||
|
|
||||||
base_path = frappe.get_app_path("erpnext", "stock", "doctype")
|
base_path = frappe.get_app_path("erpnext", "stock", "doctype")
|
||||||
response = frappe.read_file(
|
response = frappe.read_file(
|
||||||
@@ -397,7 +358,8 @@ def add_uom_data():
|
|||||||
frappe.get_doc({"doctype": "UOM Category", "category_name": _(d.get("category"))}).db_insert()
|
frappe.get_doc({"doctype": "UOM Category", "category_name": _(d.get("category"))}).db_insert()
|
||||||
|
|
||||||
if not frappe.db.exists(
|
if not frappe.db.exists(
|
||||||
"UOM Conversion Factor", {"from_uom": _(d.get("from_uom")), "to_uom": _(d.get("to_uom"))}
|
"UOM Conversion Factor",
|
||||||
|
{"from_uom": _(d.get("from_uom")), "to_uom": _(d.get("to_uom"))},
|
||||||
):
|
):
|
||||||
frappe.get_doc(
|
frappe.get_doc(
|
||||||
{
|
{
|
||||||
@@ -535,7 +497,8 @@ def create_bank_account(args):
|
|||||||
|
|
||||||
company_name = args.get("company_name")
|
company_name = args.get("company_name")
|
||||||
bank_account_group = frappe.db.get_value(
|
bank_account_group = frappe.db.get_value(
|
||||||
"Account", {"account_type": "Bank", "is_group": 1, "root_type": "Asset", "company": company_name}
|
"Account",
|
||||||
|
{"account_type": "Bank", "is_group": 1, "root_type": "Asset", "company": company_name},
|
||||||
)
|
)
|
||||||
if bank_account_group:
|
if bank_account_group:
|
||||||
bank_account = frappe.get_doc(
|
bank_account = frappe.get_doc(
|
||||||
|
|||||||
@@ -25,6 +25,12 @@ def boot_session(bootinfo):
|
|||||||
frappe.db.get_single_value("CRM Settings", "default_valid_till")
|
frappe.db.get_single_value("CRM Settings", "default_valid_till")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
bootinfo.sysdefaults.allow_sales_order_creation_for_expired_quotation = cint(
|
||||||
|
frappe.db.get_single_value(
|
||||||
|
"Selling Settings", "allow_sales_order_creation_for_expired_quotation"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
# if no company, show a dialog box to create a new company
|
# if no company, show a dialog box to create a new company
|
||||||
bootinfo.customer_count = frappe.db.sql("""SELECT count(*) FROM `tabCustomer`""")[0][0]
|
bootinfo.customer_count = frappe.db.sql("""SELECT count(*) FROM `tabCustomer`""")[0][0]
|
||||||
|
|
||||||
|
|||||||
@@ -521,6 +521,7 @@
|
|||||||
"allow_bulk_edit": 1,
|
"allow_bulk_edit": 1,
|
||||||
"fieldname": "items",
|
"fieldname": "items",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
|
"label": "Delivery Note Item",
|
||||||
"oldfieldname": "delivery_note_details",
|
"oldfieldname": "delivery_note_details",
|
||||||
"oldfieldtype": "Table",
|
"oldfieldtype": "Table",
|
||||||
"options": "Delivery Note Item",
|
"options": "Delivery Note Item",
|
||||||
@@ -666,6 +667,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "taxes",
|
"fieldname": "taxes",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
|
"label": "Sales Taxes and Charges",
|
||||||
"oldfieldname": "other_charges",
|
"oldfieldname": "other_charges",
|
||||||
"oldfieldtype": "Table",
|
"oldfieldtype": "Table",
|
||||||
"options": "Sales Taxes and Charges"
|
"options": "Sales Taxes and Charges"
|
||||||
@@ -1401,7 +1403,7 @@
|
|||||||
"idx": 146,
|
"idx": 146,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-12-12 18:38:53.067799",
|
"modified": "2023-02-14 04:45:44.179670",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Delivery Note",
|
"name": "Delivery Note",
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ frappe.listview_settings['Delivery Note'] = {
|
|||||||
return [__("Completed"), "green", "per_billed,=,100"];
|
return [__("Completed"), "green", "per_billed,=,100"];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onload: function (listview) {
|
onload: function (doclist) {
|
||||||
const action = () => {
|
const action = () => {
|
||||||
const selected_docs = doclist.get_checked_items();
|
const selected_docs = doclist.get_checked_items();
|
||||||
const docnames = doclist.get_checked_items(true);
|
const docnames = doclist.get_checked_items(true);
|
||||||
@@ -56,14 +56,14 @@ frappe.listview_settings['Delivery Note'] = {
|
|||||||
|
|
||||||
// doclist.page.add_actions_menu_item(__('Create Delivery Trip'), action, false);
|
// doclist.page.add_actions_menu_item(__('Create Delivery Trip'), action, false);
|
||||||
|
|
||||||
listview.page.add_action_item(__('Create Delivery Trip'), action);
|
doclist.page.add_action_item(__('Create Delivery Trip'), action);
|
||||||
|
|
||||||
listview.page.add_action_item(__("Sales Invoice"), ()=>{
|
doclist.page.add_action_item(__("Sales Invoice"), ()=>{
|
||||||
erpnext.bulk_transaction_processing.create(listview, "Delivery Note", "Sales Invoice");
|
erpnext.bulk_transaction_processing.create(doclist, "Delivery Note", "Sales Invoice");
|
||||||
});
|
});
|
||||||
|
|
||||||
listview.page.add_action_item(__("Packaging Slip From Delivery Note"), ()=>{
|
doclist.page.add_action_item(__("Packaging Slip From Delivery Note"), ()=>{
|
||||||
erpnext.bulk_transaction_processing.create(listview, "Delivery Note", "Packing Slip");
|
erpnext.bulk_transaction_processing.create(doclist, "Delivery Note", "Packing Slip");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -706,7 +706,7 @@
|
|||||||
"depends_on": "enable_deferred_expense",
|
"depends_on": "enable_deferred_expense",
|
||||||
"fieldname": "no_of_months_exp",
|
"fieldname": "no_of_months_exp",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Int",
|
||||||
"label": "No of Months"
|
"label": "No of Months (Expense)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"collapsible": 1,
|
"collapsible": 1,
|
||||||
@@ -911,7 +911,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"make_attachments_public": 1,
|
"make_attachments_public": 1,
|
||||||
"modified": "2023-01-07 22:45:00.341745",
|
"modified": "2023-02-14 04:48:26.343620",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Item",
|
"name": "Item",
|
||||||
|
|||||||
@@ -38,5 +38,19 @@
|
|||||||
"price_list_rate": 1000,
|
"price_list_rate": 1000,
|
||||||
"valid_from": "2017-04-10",
|
"valid_from": "2017-04-10",
|
||||||
"valid_upto": "2017-04-17"
|
"valid_upto": "2017-04-17"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "Item Price",
|
||||||
|
"item_code": "_Test Item",
|
||||||
|
"price_list": "_Test Buying Price List",
|
||||||
|
"price_list_rate": 100,
|
||||||
|
"supplier": "_Test Supplier"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "Item Price",
|
||||||
|
"item_code": "_Test Item",
|
||||||
|
"price_list": "_Test Selling Price List",
|
||||||
|
"price_list_rate": 200,
|
||||||
|
"customer": "_Test Customer"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -110,8 +110,11 @@ frappe.ui.form.on('Material Request', {
|
|||||||
|
|
||||||
if (frm.doc.material_request_type === "Material Transfer") {
|
if (frm.doc.material_request_type === "Material Transfer") {
|
||||||
add_create_pick_list_button();
|
add_create_pick_list_button();
|
||||||
frm.add_custom_button(__("Transfer Material"),
|
frm.add_custom_button(__("Material Transfer"),
|
||||||
() => frm.events.make_stock_entry(frm), __('Create'));
|
() => frm.events.make_stock_entry(frm), __('Create'));
|
||||||
|
|
||||||
|
frm.add_custom_button(__("Material Transfer (In Transit)"),
|
||||||
|
() => frm.events.make_in_transit_stock_entry(frm), __('Create'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frm.doc.material_request_type === "Material Issue") {
|
if (frm.doc.material_request_type === "Material Issue") {
|
||||||
@@ -333,6 +336,46 @@ frappe.ui.form.on('Material Request', {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
make_in_transit_stock_entry(frm) {
|
||||||
|
frappe.prompt(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
label: __('In Transit Warehouse'),
|
||||||
|
fieldname: 'in_transit_warehouse',
|
||||||
|
fieldtype: 'Link',
|
||||||
|
options: 'Warehouse',
|
||||||
|
reqd: 1,
|
||||||
|
get_query: () => {
|
||||||
|
return{
|
||||||
|
filters: {
|
||||||
|
'company': frm.doc.company,
|
||||||
|
'is_group': 0,
|
||||||
|
'warehouse_type': 'Transit'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
(values) => {
|
||||||
|
frappe.call({
|
||||||
|
method: "erpnext.stock.doctype.material_request.material_request.make_in_transit_stock_entry",
|
||||||
|
args: {
|
||||||
|
source_name: frm.doc.name,
|
||||||
|
in_transit_warehouse: values.in_transit_warehouse
|
||||||
|
},
|
||||||
|
callback: function(r) {
|
||||||
|
if (r.message) {
|
||||||
|
let doc = frappe.model.sync(r.message);
|
||||||
|
frappe.set_route('Form', doc[0].doctype, doc[0].name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
__('In Transit Transfer'),
|
||||||
|
__("Create Stock Entry")
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
create_pick_list: (frm) => {
|
create_pick_list: (frm) => {
|
||||||
frappe.model.open_mapped_doc({
|
frappe.model.open_mapped_doc({
|
||||||
method: "erpnext.stock.doctype.material_request.material_request.create_pick_list",
|
method: "erpnext.stock.doctype.material_request.material_request.create_pick_list",
|
||||||
|
|||||||
@@ -716,3 +716,14 @@ def create_pick_list(source_name, target_doc=None):
|
|||||||
doc.set_item_locations()
|
doc.set_item_locations()
|
||||||
|
|
||||||
return doc
|
return doc
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def make_in_transit_stock_entry(source_name, in_transit_warehouse):
|
||||||
|
ste_doc = make_stock_entry(source_name)
|
||||||
|
ste_doc.add_to_transit = 1
|
||||||
|
|
||||||
|
for row in ste_doc.items:
|
||||||
|
row.t_warehouse = in_transit_warehouse
|
||||||
|
|
||||||
|
return ste_doc
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ from frappe.utils import flt, today
|
|||||||
|
|
||||||
from erpnext.stock.doctype.item.test_item import create_item
|
from erpnext.stock.doctype.item.test_item import create_item
|
||||||
from erpnext.stock.doctype.material_request.material_request import (
|
from erpnext.stock.doctype.material_request.material_request import (
|
||||||
|
make_in_transit_stock_entry,
|
||||||
make_purchase_order,
|
make_purchase_order,
|
||||||
make_stock_entry,
|
make_stock_entry,
|
||||||
make_supplier_quotation,
|
make_supplier_quotation,
|
||||||
@@ -56,6 +57,22 @@ class TestMaterialRequest(FrappeTestCase):
|
|||||||
self.assertEqual(se.doctype, "Stock Entry")
|
self.assertEqual(se.doctype, "Stock Entry")
|
||||||
self.assertEqual(len(se.get("items")), len(mr.get("items")))
|
self.assertEqual(len(se.get("items")), len(mr.get("items")))
|
||||||
|
|
||||||
|
def test_in_transit_make_stock_entry(self):
|
||||||
|
mr = frappe.copy_doc(test_records[0]).insert()
|
||||||
|
|
||||||
|
self.assertRaises(frappe.ValidationError, make_stock_entry, mr.name)
|
||||||
|
|
||||||
|
mr = frappe.get_doc("Material Request", mr.name)
|
||||||
|
mr.material_request_type = "Material Transfer"
|
||||||
|
mr.submit()
|
||||||
|
|
||||||
|
in_transit_warehouse = get_in_transit_warehouse(mr.company)
|
||||||
|
se = make_in_transit_stock_entry(mr.name, in_transit_warehouse)
|
||||||
|
|
||||||
|
self.assertEqual(se.doctype, "Stock Entry")
|
||||||
|
for row in se.get("items"):
|
||||||
|
self.assertEqual(row.t_warehouse, in_transit_warehouse)
|
||||||
|
|
||||||
def _insert_stock_entry(self, qty1, qty2, warehouse=None):
|
def _insert_stock_entry(self, qty1, qty2, warehouse=None):
|
||||||
se = frappe.get_doc(
|
se = frappe.get_doc(
|
||||||
{
|
{
|
||||||
@@ -742,6 +759,36 @@ class TestMaterialRequest(FrappeTestCase):
|
|||||||
self.assertEqual(existing_requested_qty, current_requested_qty)
|
self.assertEqual(existing_requested_qty, current_requested_qty)
|
||||||
|
|
||||||
|
|
||||||
|
def get_in_transit_warehouse(company):
|
||||||
|
if not frappe.db.exists("Warehouse Type", "Transit"):
|
||||||
|
frappe.get_doc(
|
||||||
|
{
|
||||||
|
"doctype": "Warehouse Type",
|
||||||
|
"name": "Transit",
|
||||||
|
}
|
||||||
|
).insert()
|
||||||
|
|
||||||
|
in_transit_warehouse = frappe.db.exists(
|
||||||
|
"Warehouse", {"warehouse_type": "Transit", "company": company}
|
||||||
|
)
|
||||||
|
|
||||||
|
if not in_transit_warehouse:
|
||||||
|
in_transit_warehouse = (
|
||||||
|
frappe.get_doc(
|
||||||
|
{
|
||||||
|
"doctype": "Warehouse",
|
||||||
|
"warehouse_name": "Transit",
|
||||||
|
"warehouse_type": "Transit",
|
||||||
|
"company": company,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.insert()
|
||||||
|
.name
|
||||||
|
)
|
||||||
|
|
||||||
|
return in_transit_warehouse
|
||||||
|
|
||||||
|
|
||||||
def make_material_request(**args):
|
def make_material_request(**args):
|
||||||
args = frappe._dict(args)
|
args = frappe._dict(args)
|
||||||
mr = frappe.new_doc("Material Request")
|
mr = frappe.new_doc("Material Request")
|
||||||
|
|||||||
@@ -31,5 +31,21 @@
|
|||||||
"enabled": 1,
|
"enabled": 1,
|
||||||
"price_list_name": "_Test Price List Rest of the World",
|
"price_list_name": "_Test Price List Rest of the World",
|
||||||
"selling": 1
|
"selling": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buying": 0,
|
||||||
|
"currency": "USD",
|
||||||
|
"doctype": "Price List",
|
||||||
|
"enabled": 1,
|
||||||
|
"price_list_name": "_Test Selling Price List",
|
||||||
|
"selling": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buying": 1,
|
||||||
|
"currency": "USD",
|
||||||
|
"doctype": "Price List",
|
||||||
|
"enabled": 1,
|
||||||
|
"price_list_name": "_Test Buying Price List",
|
||||||
|
"selling": 0
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -88,8 +88,15 @@ def get_item_details(args, doc=None, for_validate=False, overwrite_warehouse=Tru
|
|||||||
|
|
||||||
update_party_blanket_order(args, out)
|
update_party_blanket_order(args, out)
|
||||||
|
|
||||||
|
# Never try to find a customer price if customer is set in these Doctype
|
||||||
|
current_customer = args.customer
|
||||||
|
if args.get("doctype") in ["Purchase Order", "Purchase Receipt", "Purchase Invoice"]:
|
||||||
|
args.customer = None
|
||||||
|
|
||||||
out.update(get_price_list_rate(args, item))
|
out.update(get_price_list_rate(args, item))
|
||||||
|
|
||||||
|
args.customer = current_customer
|
||||||
|
|
||||||
if args.customer and cint(args.is_pos):
|
if args.customer and cint(args.is_pos):
|
||||||
out.update(get_pos_profile_item_details(args.company, args, update_data=True))
|
out.update(get_pos_profile_item_details(args.company, args, update_data=True))
|
||||||
|
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ def get_reserved_qty(item_code, warehouse):
|
|||||||
and parenttype='Sales Order'
|
and parenttype='Sales Order'
|
||||||
and item_code != parent_item
|
and item_code != parent_item
|
||||||
and exists (select * from `tabSales Order` so
|
and exists (select * from `tabSales Order` so
|
||||||
where name = dnpi_in.parent and docstatus = 1 and status != 'Closed')
|
where name = dnpi_in.parent and docstatus = 1 and status not in ('On Hold', 'Closed'))
|
||||||
) dnpi)
|
) dnpi)
|
||||||
union
|
union
|
||||||
(select stock_qty as dnpi_qty, qty as so_item_qty,
|
(select stock_qty as dnpi_qty, qty as so_item_qty,
|
||||||
@@ -131,7 +131,7 @@ def get_reserved_qty(item_code, warehouse):
|
|||||||
and (so_item.delivered_by_supplier is null or so_item.delivered_by_supplier = 0)
|
and (so_item.delivered_by_supplier is null or so_item.delivered_by_supplier = 0)
|
||||||
and exists(select * from `tabSales Order` so
|
and exists(select * from `tabSales Order` so
|
||||||
where so.name = so_item.parent and so.docstatus = 1
|
where so.name = so_item.parent and so.docstatus = 1
|
||||||
and so.status != 'Closed'))
|
and so.status not in ('On Hold', 'Closed')))
|
||||||
) tab
|
) tab
|
||||||
where
|
where
|
||||||
so_item_qty >= so_item_delivered_qty
|
so_item_qty >= so_item_delivered_qty
|
||||||
|
|||||||
40
erpnext/stock/tests/test_get_item_details.py
Normal file
40
erpnext/stock/tests/test_get_item_details.py
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
from frappe.test_runner import make_test_records
|
||||||
|
from frappe.tests.utils import FrappeTestCase
|
||||||
|
|
||||||
|
from erpnext.stock.get_item_details import get_item_details
|
||||||
|
|
||||||
|
test_ignore = ["BOM"]
|
||||||
|
test_dependencies = ["Customer", "Supplier", "Item", "Price List", "Item Price"]
|
||||||
|
|
||||||
|
|
||||||
|
class TestGetItemDetail(FrappeTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
make_test_records("Price List")
|
||||||
|
super().setUp()
|
||||||
|
|
||||||
|
def test_get_item_detail_purchase_order(self):
|
||||||
|
|
||||||
|
args = frappe._dict(
|
||||||
|
{
|
||||||
|
"item_code": "_Test Item",
|
||||||
|
"company": "_Test Company",
|
||||||
|
"customer": "_Test Customer",
|
||||||
|
"conversion_rate": 1.0,
|
||||||
|
"price_list_currency": "USD",
|
||||||
|
"plc_conversion_rate": 1.0,
|
||||||
|
"doctype": "Purchase Order",
|
||||||
|
"name": None,
|
||||||
|
"supplier": "_Test Supplier",
|
||||||
|
"transaction_date": None,
|
||||||
|
"conversion_rate": 1.0,
|
||||||
|
"price_list": "_Test Buying Price List",
|
||||||
|
"is_subcontracted": 0,
|
||||||
|
"ignore_pricing_rule": 1,
|
||||||
|
"qty": 1,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
details = get_item_details(args)
|
||||||
|
self.assertEqual(details.get("price_list_rate"), 100)
|
||||||
@@ -51,13 +51,31 @@ frappe.ui.form.on('Subcontracting Receipt', {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
frm.set_query("expense_account", "items", function () {
|
frm.set_query('expense_account', 'items', function () {
|
||||||
return {
|
return {
|
||||||
query: "erpnext.controllers.queries.get_expense_account",
|
query: 'erpnext.controllers.queries.get_expense_account',
|
||||||
filters: { 'company': frm.doc.company }
|
filters: { 'company': frm.doc.company }
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
frm.set_query('batch_no', 'items', function(doc, cdt, cdn) {
|
||||||
|
var row = locals[cdt][cdn];
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
item: row.item_code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let batch_no_field = frm.get_docfield("items", "batch_no");
|
||||||
|
if (batch_no_field) {
|
||||||
|
batch_no_field.get_route_options_for_new_doc = function(row) {
|
||||||
|
return {
|
||||||
|
"item": row.doc.item_code
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
frappe.db.get_single_value('Buying Settings', 'backflush_raw_materials_of_subcontract_based_on').then(val => {
|
frappe.db.get_single_value('Buying Settings', 'backflush_raw_materials_of_subcontract_based_on').then(val => {
|
||||||
if (val == 'Material Transferred for Subcontract') {
|
if (val == 'Material Transferred for Subcontract') {
|
||||||
frm.fields_dict['supplied_items'].grid.grid_rows.forEach((grid_row) => {
|
frm.fields_dict['supplied_items'].grid.grid_rows.forEach((grid_row) => {
|
||||||
@@ -73,7 +91,7 @@ frappe.ui.form.on('Subcontracting Receipt', {
|
|||||||
|
|
||||||
refresh: (frm) => {
|
refresh: (frm) => {
|
||||||
if (frm.doc.docstatus > 0) {
|
if (frm.doc.docstatus > 0) {
|
||||||
frm.add_custom_button(__("Stock Ledger"), function () {
|
frm.add_custom_button(__('Stock Ledger'), function () {
|
||||||
frappe.route_options = {
|
frappe.route_options = {
|
||||||
voucher_no: frm.doc.name,
|
voucher_no: frm.doc.name,
|
||||||
from_date: frm.doc.posting_date,
|
from_date: frm.doc.posting_date,
|
||||||
@@ -81,8 +99,8 @@ frappe.ui.form.on('Subcontracting Receipt', {
|
|||||||
company: frm.doc.company,
|
company: frm.doc.company,
|
||||||
show_cancelled_entries: frm.doc.docstatus === 2
|
show_cancelled_entries: frm.doc.docstatus === 2
|
||||||
};
|
};
|
||||||
frappe.set_route("query-report", "Stock Ledger");
|
frappe.set_route('query-report', 'Stock Ledger');
|
||||||
}, __("View"));
|
}, __('View'));
|
||||||
|
|
||||||
frm.add_custom_button(__('Accounting Ledger'), function () {
|
frm.add_custom_button(__('Accounting Ledger'), function () {
|
||||||
frappe.route_options = {
|
frappe.route_options = {
|
||||||
@@ -90,11 +108,11 @@ frappe.ui.form.on('Subcontracting Receipt', {
|
|||||||
from_date: frm.doc.posting_date,
|
from_date: frm.doc.posting_date,
|
||||||
to_date: moment(frm.doc.modified).format('YYYY-MM-DD'),
|
to_date: moment(frm.doc.modified).format('YYYY-MM-DD'),
|
||||||
company: frm.doc.company,
|
company: frm.doc.company,
|
||||||
group_by: "Group by Voucher (Consolidated)",
|
group_by: 'Group by Voucher (Consolidated)',
|
||||||
show_cancelled_entries: frm.doc.docstatus === 2
|
show_cancelled_entries: frm.doc.docstatus === 2
|
||||||
};
|
};
|
||||||
frappe.set_route("query-report", "General Ledger");
|
frappe.set_route('query-report', 'General Ledger');
|
||||||
}, __("View"));
|
}, __('View'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!frm.doc.is_return && frm.doc.docstatus == 1 && frm.doc.per_returned < 100) {
|
if (!frm.doc.is_return && frm.doc.docstatus == 1 && frm.doc.per_returned < 100) {
|
||||||
@@ -111,25 +129,25 @@ frappe.ui.form.on('Subcontracting Receipt', {
|
|||||||
frm.add_custom_button(__('Subcontracting Order'), function () {
|
frm.add_custom_button(__('Subcontracting Order'), function () {
|
||||||
if (!frm.doc.supplier) {
|
if (!frm.doc.supplier) {
|
||||||
frappe.throw({
|
frappe.throw({
|
||||||
title: __("Mandatory"),
|
title: __('Mandatory'),
|
||||||
message: __("Please Select a Supplier")
|
message: __('Please Select a Supplier')
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
erpnext.utils.map_current_doc({
|
erpnext.utils.map_current_doc({
|
||||||
method: 'erpnext.subcontracting.doctype.subcontracting_order.subcontracting_order.make_subcontracting_receipt',
|
method: 'erpnext.subcontracting.doctype.subcontracting_order.subcontracting_order.make_subcontracting_receipt',
|
||||||
source_doctype: "Subcontracting Order",
|
source_doctype: 'Subcontracting Order',
|
||||||
target: frm,
|
target: frm,
|
||||||
setters: {
|
setters: {
|
||||||
supplier: frm.doc.supplier,
|
supplier: frm.doc.supplier,
|
||||||
},
|
},
|
||||||
get_query_filters: {
|
get_query_filters: {
|
||||||
docstatus: 1,
|
docstatus: 1,
|
||||||
per_received: ["<", 100],
|
per_received: ['<', 100],
|
||||||
company: frm.doc.company
|
company: frm.doc.company
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, __("Get Items From"));
|
}, __('Get Items From'));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user