Compare commits
9 Commits
v15.21.0
...
holiday_so
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2c5ea7417c | ||
|
|
2a7d1c4c8d | ||
|
|
14b009b093 | ||
|
|
530922848f | ||
|
|
79d51a0a0b | ||
|
|
ce7ac29d06 | ||
|
|
ff7108a3b1 | ||
|
|
77cc91d06b | ||
|
|
40cdde8820 |
1
.github/workflows/patch.yml
vendored
1
.github/workflows/patch.yml
vendored
@@ -134,6 +134,7 @@ jobs:
|
|||||||
}
|
}
|
||||||
|
|
||||||
update_to_version 14
|
update_to_version 14
|
||||||
|
update_to_version 15
|
||||||
|
|
||||||
echo "Updating to latest version"
|
echo "Updating to latest version"
|
||||||
git -C "apps/frappe" checkout -q -f "${GITHUB_BASE_REF:-${GITHUB_REF##*/}}"
|
git -C "apps/frappe" checkout -q -f "${GITHUB_BASE_REF:-${GITHUB_REF##*/}}"
|
||||||
|
|||||||
46
.mergify.yml
46
.mergify.yml
@@ -17,6 +17,7 @@ pull_request_rules:
|
|||||||
- base=version-12
|
- base=version-12
|
||||||
- base=version-14
|
- base=version-14
|
||||||
- base=version-15
|
- base=version-15
|
||||||
|
- base=version-16
|
||||||
actions:
|
actions:
|
||||||
close:
|
close:
|
||||||
comment:
|
comment:
|
||||||
@@ -24,16 +25,6 @@ pull_request_rules:
|
|||||||
@{{author}}, thanks for the contribution, but we do not accept pull requests on a stable branch. Please raise PR on an appropriate hotfix branch.
|
@{{author}}, thanks for the contribution, but we do not accept pull requests on a stable branch. Please raise PR on an appropriate hotfix branch.
|
||||||
https://github.com/frappe/erpnext/wiki/Pull-Request-Checklist#which-branch
|
https://github.com/frappe/erpnext/wiki/Pull-Request-Checklist#which-branch
|
||||||
|
|
||||||
- name: Auto-close PRs on pre-release branch
|
|
||||||
conditions:
|
|
||||||
- base=version-13-pre-release
|
|
||||||
actions:
|
|
||||||
close:
|
|
||||||
comment:
|
|
||||||
message: |
|
|
||||||
@{{author}}, pre-release branch is not maintained anymore. Releases are directly done by merging hotfix branch to stable branches.
|
|
||||||
|
|
||||||
|
|
||||||
- name: backport to develop
|
- name: backport to develop
|
||||||
conditions:
|
conditions:
|
||||||
- label="backport develop"
|
- label="backport develop"
|
||||||
@@ -54,13 +45,13 @@ pull_request_rules:
|
|||||||
assignees:
|
assignees:
|
||||||
- "{{ author }}"
|
- "{{ author }}"
|
||||||
|
|
||||||
- name: backport to version-14-pre-release
|
- name: backport to version-15-hotfix
|
||||||
conditions:
|
conditions:
|
||||||
- label="backport version-14-pre-release"
|
- label="backport version-15-hotfix"
|
||||||
actions:
|
actions:
|
||||||
backport:
|
backport:
|
||||||
branches:
|
branches:
|
||||||
- version-14-pre-release
|
- version-15-hotfix
|
||||||
assignees:
|
assignees:
|
||||||
- "{{ author }}"
|
- "{{ author }}"
|
||||||
|
|
||||||
@@ -74,35 +65,6 @@ pull_request_rules:
|
|||||||
assignees:
|
assignees:
|
||||||
- "{{ author }}"
|
- "{{ author }}"
|
||||||
|
|
||||||
- name: backport to version-13-pre-release
|
|
||||||
conditions:
|
|
||||||
- label="backport version-13-pre-release"
|
|
||||||
actions:
|
|
||||||
backport:
|
|
||||||
branches:
|
|
||||||
- version-13-pre-release
|
|
||||||
assignees:
|
|
||||||
- "{{ author }}"
|
|
||||||
|
|
||||||
- name: backport to version-12-hotfix
|
|
||||||
conditions:
|
|
||||||
- label="backport version-12-hotfix"
|
|
||||||
actions:
|
|
||||||
backport:
|
|
||||||
branches:
|
|
||||||
- version-12-hotfix
|
|
||||||
assignees:
|
|
||||||
- "{{ author }}"
|
|
||||||
|
|
||||||
- name: backport to version-12-pre-release
|
|
||||||
conditions:
|
|
||||||
- label="backport version-12-pre-release"
|
|
||||||
actions:
|
|
||||||
backport:
|
|
||||||
branches:
|
|
||||||
- version-12-pre-release
|
|
||||||
assignees:
|
|
||||||
- "{{ author }}"
|
|
||||||
|
|
||||||
- name: Automatic merge on CI success and review
|
- name: Automatic merge on CI success and review
|
||||||
conditions:
|
conditions:
|
||||||
|
|||||||
@@ -454,7 +454,7 @@ def create_merge_logs(invoice_by_customer, closing_entry=None):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
frappe.db.rollback()
|
frappe.db.rollback()
|
||||||
message_log = frappe.message_log.pop() if frappe.message_log else str(e)
|
message_log = frappe.message_log.pop() if frappe.message_log else str(e)
|
||||||
error_message = safe_load_json(message_log)
|
error_message = get_error_message(message_log)
|
||||||
|
|
||||||
if closing_entry:
|
if closing_entry:
|
||||||
closing_entry.set_status(update=True, status="Failed")
|
closing_entry.set_status(update=True, status="Failed")
|
||||||
@@ -483,7 +483,7 @@ def cancel_merge_logs(merge_logs, closing_entry=None):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
frappe.db.rollback()
|
frappe.db.rollback()
|
||||||
message_log = frappe.message_log.pop() if frappe.message_log else str(e)
|
message_log = frappe.message_log.pop() if frappe.message_log else str(e)
|
||||||
error_message = safe_load_json(message_log)
|
error_message = get_error_message(message_log)
|
||||||
|
|
||||||
if closing_entry:
|
if closing_entry:
|
||||||
closing_entry.set_status(update=True, status="Submitted")
|
closing_entry.set_status(update=True, status="Submitted")
|
||||||
@@ -525,10 +525,8 @@ def check_scheduler_status():
|
|||||||
frappe.throw(_("Scheduler is inactive. Cannot enqueue job."), title=_("Scheduler Inactive"))
|
frappe.throw(_("Scheduler is inactive. Cannot enqueue job."), title=_("Scheduler Inactive"))
|
||||||
|
|
||||||
|
|
||||||
def safe_load_json(message):
|
def get_error_message(message) -> str:
|
||||||
try:
|
try:
|
||||||
json_message = json.loads(message).get("message")
|
return message["message"]
|
||||||
except Exception:
|
except Exception:
|
||||||
json_message = message
|
return str(message)
|
||||||
|
|
||||||
return json_message
|
|
||||||
|
|||||||
@@ -1066,7 +1066,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
"debit_in_account_currency": (
|
"debit_in_account_currency": (
|
||||||
base_asset_amount if cwip_account_currency == self.company_currency else asset_amount
|
base_asset_amount if cwip_account_currency == self.company_currency else asset_amount
|
||||||
),
|
),
|
||||||
"cost_center": self.cost_center,
|
"cost_center": item.cost_center or self.cost_center,
|
||||||
"project": item.project or self.project,
|
"project": item.project or self.project,
|
||||||
},
|
},
|
||||||
item=item,
|
item=item,
|
||||||
|
|||||||
@@ -1949,6 +1949,30 @@ class TestPurchaseInvoice(FrappeTestCase, StockTestMixin):
|
|||||||
self.assertEqual(po.docstatus, 1)
|
self.assertEqual(po.docstatus, 1)
|
||||||
self.assertEqual(pi.docstatus, 1)
|
self.assertEqual(pi.docstatus, 1)
|
||||||
|
|
||||||
|
def test_default_cost_center_for_purchase(self):
|
||||||
|
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
|
||||||
|
|
||||||
|
for c_center in ["_Test Cost Center Selling", "_Test Cost Center Buying"]:
|
||||||
|
create_cost_center(cost_center_name=c_center)
|
||||||
|
|
||||||
|
item = create_item(
|
||||||
|
"_Test Cost Center Item For Purchase",
|
||||||
|
is_stock_item=1,
|
||||||
|
buying_cost_center="_Test Cost Center Buying - _TC",
|
||||||
|
selling_cost_center="_Test Cost Center Selling - _TC",
|
||||||
|
)
|
||||||
|
|
||||||
|
pi = make_purchase_invoice(
|
||||||
|
item=item.name, qty=1, rate=1000, update_stock=True, do_not_submit=True, cost_center=""
|
||||||
|
)
|
||||||
|
|
||||||
|
pi.items[0].cost_center = ""
|
||||||
|
pi.set_missing_values()
|
||||||
|
pi.calculate_taxes_and_totals()
|
||||||
|
pi.save()
|
||||||
|
|
||||||
|
self.assertEqual(pi.items[0].cost_center, "_Test Cost Center Buying - _TC")
|
||||||
|
|
||||||
|
|
||||||
def set_advance_flag(company, flag, default_account):
|
def set_advance_flag(company, flag, default_account):
|
||||||
frappe.db.set_value(
|
frappe.db.set_value(
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ class StockController(AccountsController):
|
|||||||
elif self.doctype in ["Purchase Receipt", "Purchase Invoice"] and self.docstatus == 1:
|
elif self.doctype in ["Purchase Receipt", "Purchase Invoice"] and self.docstatus == 1:
|
||||||
gl_entries = []
|
gl_entries = []
|
||||||
gl_entries = self.get_asset_gl_entry(gl_entries)
|
gl_entries = self.get_asset_gl_entry(gl_entries)
|
||||||
|
update_regional_gl_entries(gl_entries, self)
|
||||||
make_gl_entries(gl_entries, from_repost=from_repost)
|
make_gl_entries(gl_entries, from_repost=from_repost)
|
||||||
|
|
||||||
def validate_serialized_batch(self):
|
def validate_serialized_batch(self):
|
||||||
@@ -855,8 +856,9 @@ class StockController(AccountsController):
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def show_accounting_ledger_preview(company, doctype, docname):
|
def show_accounting_ledger_preview(company, doctype, docname):
|
||||||
filters = {"company": company, "include_dimensions": 1}
|
filters = frappe._dict(company=company, include_dimensions=1)
|
||||||
doc = frappe.get_doc(doctype, docname)
|
doc = frappe.get_doc(doctype, docname)
|
||||||
|
doc.run_method("before_gl_preview")
|
||||||
|
|
||||||
gl_columns, gl_data = get_accounting_ledger_preview(doc, filters)
|
gl_columns, gl_data = get_accounting_ledger_preview(doc, filters)
|
||||||
|
|
||||||
@@ -867,8 +869,9 @@ def show_accounting_ledger_preview(company, doctype, docname):
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def show_stock_ledger_preview(company, doctype, docname):
|
def show_stock_ledger_preview(company, doctype, docname):
|
||||||
filters = {"company": company}
|
filters = frappe._dict(company=company)
|
||||||
doc = frappe.get_doc(doctype, docname)
|
doc = frappe.get_doc(doctype, docname)
|
||||||
|
doc.run_method("before_sl_preview")
|
||||||
|
|
||||||
sl_columns, sl_data = get_stock_ledger_preview(doc, filters)
|
sl_columns, sl_data = get_stock_ledger_preview(doc, filters)
|
||||||
|
|
||||||
@@ -1216,3 +1219,8 @@ def create_item_wise_repost_entries(voucher_type, voucher_no, allow_zero_rate=Fa
|
|||||||
repost_entries.append(repost_entry)
|
repost_entries.append(repost_entry)
|
||||||
|
|
||||||
return repost_entries
|
return repost_entries
|
||||||
|
|
||||||
|
|
||||||
|
@erpnext.allow_regional
|
||||||
|
def update_regional_gl_entries(gl_list, doc):
|
||||||
|
return
|
||||||
|
|||||||
@@ -80,9 +80,9 @@ class HolidayList(Document):
|
|||||||
self.sort_holidays()
|
self.sort_holidays()
|
||||||
|
|
||||||
def sort_holidays(self):
|
def sort_holidays(self):
|
||||||
self.holidays.sort(key=lambda x: getdate(x.holiday_date))
|
self.holidays.sort(key=lambda x: (x.weekly_off, getdate(x.holiday_date)))
|
||||||
for i in range(len(self.holidays)):
|
for row, idx in enumerate(self.holidays, start=1):
|
||||||
self.holidays[i].idx = i + 1
|
row.idx = idx
|
||||||
|
|
||||||
def get_holidays(self) -> list[date]:
|
def get_holidays(self) -> list[date]:
|
||||||
return [getdate(holiday.holiday_date) for holiday in self.holidays]
|
return [getdate(holiday.holiday_date) for holiday in self.holidays]
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ frappe.ui.form.on('Delivery Trip', {
|
|||||||
company: frm.doc.company,
|
company: frm.doc.company,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}, __("Get customers from"));
|
}, __("Get stops from"));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -907,6 +907,8 @@ def create_item(
|
|||||||
opening_stock=0,
|
opening_stock=0,
|
||||||
is_fixed_asset=0,
|
is_fixed_asset=0,
|
||||||
asset_category=None,
|
asset_category=None,
|
||||||
|
buying_cost_center=None,
|
||||||
|
selling_cost_center=None,
|
||||||
company="_Test Company",
|
company="_Test Company",
|
||||||
):
|
):
|
||||||
if not frappe.db.exists("Item", item_code):
|
if not frappe.db.exists("Item", item_code):
|
||||||
@@ -924,7 +926,15 @@ def create_item(
|
|||||||
item.is_purchase_item = is_purchase_item
|
item.is_purchase_item = is_purchase_item
|
||||||
item.is_customer_provided_item = is_customer_provided_item
|
item.is_customer_provided_item = is_customer_provided_item
|
||||||
item.customer = customer or ""
|
item.customer = customer or ""
|
||||||
item.append("item_defaults", {"default_warehouse": warehouse, "company": company})
|
item.append(
|
||||||
|
"item_defaults",
|
||||||
|
{
|
||||||
|
"default_warehouse": warehouse,
|
||||||
|
"company": company,
|
||||||
|
"selling_cost_center": selling_cost_center,
|
||||||
|
"buying_cost_center": buying_cost_center,
|
||||||
|
},
|
||||||
|
)
|
||||||
item.save()
|
item.save()
|
||||||
else:
|
else:
|
||||||
item = frappe.get_doc("Item", item_code)
|
item = frappe.get_doc("Item", item_code)
|
||||||
|
|||||||
@@ -314,6 +314,7 @@ class PurchaseReceipt(BuyingController):
|
|||||||
self.make_item_gl_entries(gl_entries, warehouse_account=warehouse_account)
|
self.make_item_gl_entries(gl_entries, warehouse_account=warehouse_account)
|
||||||
self.make_tax_gl_entries(gl_entries)
|
self.make_tax_gl_entries(gl_entries)
|
||||||
self.get_asset_gl_entry(gl_entries)
|
self.get_asset_gl_entry(gl_entries)
|
||||||
|
update_regional_gl_entries(gl_entries, self)
|
||||||
|
|
||||||
return process_gl_map(gl_entries)
|
return process_gl_map(gl_entries)
|
||||||
|
|
||||||
@@ -821,16 +822,14 @@ class PurchaseReceipt(BuyingController):
|
|||||||
po_details.append(d.purchase_order_item)
|
po_details.append(d.purchase_order_item)
|
||||||
|
|
||||||
if po_details:
|
if po_details:
|
||||||
updated_pr += update_billed_amount_based_on_po(po_details, update_modified)
|
updated_pr += update_billed_amount_based_on_po(po_details, update_modified, self)
|
||||||
|
|
||||||
for pr in set(updated_pr):
|
for pr in set(updated_pr):
|
||||||
pr_doc = self if (pr == self.name) else frappe.get_doc("Purchase Receipt", pr)
|
pr_doc = self if (pr == self.name) else frappe.get_doc("Purchase Receipt", pr)
|
||||||
update_billing_percentage(pr_doc, update_modified=update_modified)
|
update_billing_percentage(pr_doc, update_modified=update_modified)
|
||||||
|
|
||||||
self.load_from_db()
|
|
||||||
|
|
||||||
|
def update_billed_amount_based_on_po(po_details, update_modified=True, pr_doc=None):
|
||||||
def update_billed_amount_based_on_po(po_details, update_modified=True):
|
|
||||||
po_billed_amt_details = get_billed_amount_against_po(po_details)
|
po_billed_amt_details = get_billed_amount_against_po(po_details)
|
||||||
|
|
||||||
# Get all Purchase Receipt Item rows against the Purchase Order Items
|
# Get all Purchase Receipt Item rows against the Purchase Order Items
|
||||||
@@ -859,13 +858,19 @@ def update_billed_amount_based_on_po(po_details, update_modified=True):
|
|||||||
po_billed_amt_details[pr_item.purchase_order_item] = billed_against_po
|
po_billed_amt_details[pr_item.purchase_order_item] = billed_against_po
|
||||||
|
|
||||||
if pr_item.billed_amt != billed_amt_agianst_pr:
|
if pr_item.billed_amt != billed_amt_agianst_pr:
|
||||||
frappe.db.set_value(
|
# update existing doc if possible
|
||||||
"Purchase Receipt Item",
|
if pr_doc and pr_item.parent == pr_doc.name:
|
||||||
pr_item.name,
|
pr_item = next((item for item in pr_doc.items if item.name == pr_item.name), None)
|
||||||
"billed_amt",
|
pr_item.db_set("billed_amt", billed_amt_agianst_pr, update_modified=update_modified)
|
||||||
billed_amt_agianst_pr,
|
|
||||||
update_modified=update_modified,
|
else:
|
||||||
)
|
frappe.db.set_value(
|
||||||
|
"Purchase Receipt Item",
|
||||||
|
pr_item.name,
|
||||||
|
"billed_amt",
|
||||||
|
billed_amt_agianst_pr,
|
||||||
|
update_modified=update_modified,
|
||||||
|
)
|
||||||
|
|
||||||
updated_pr.append(pr_item.parent)
|
updated_pr.append(pr_item.parent)
|
||||||
|
|
||||||
@@ -941,9 +946,6 @@ def get_billed_amount_against_po(po_items):
|
|||||||
|
|
||||||
|
|
||||||
def update_billing_percentage(pr_doc, update_modified=True, adjust_incoming_rate=False):
|
def update_billing_percentage(pr_doc, update_modified=True, adjust_incoming_rate=False):
|
||||||
# Reload as billed amount was set in db directly
|
|
||||||
pr_doc.load_from_db()
|
|
||||||
|
|
||||||
# Update Billing % based on pending accepted qty
|
# Update Billing % based on pending accepted qty
|
||||||
total_amount, total_billed_amount = 0, 0
|
total_amount, total_billed_amount = 0, 0
|
||||||
item_wise_returned_qty = get_item_wise_returned_qty(pr_doc)
|
item_wise_returned_qty = get_item_wise_returned_qty(pr_doc)
|
||||||
@@ -969,7 +971,6 @@ def update_billing_percentage(pr_doc, update_modified=True, adjust_incoming_rate
|
|||||||
|
|
||||||
percent_billed = round(100 * (total_billed_amount / (total_amount or 1)), 6)
|
percent_billed = round(100 * (total_billed_amount / (total_amount or 1)), 6)
|
||||||
pr_doc.db_set("per_billed", percent_billed)
|
pr_doc.db_set("per_billed", percent_billed)
|
||||||
pr_doc.load_from_db()
|
|
||||||
|
|
||||||
if update_modified:
|
if update_modified:
|
||||||
pr_doc.set_status(update=True)
|
pr_doc.set_status(update=True)
|
||||||
@@ -1255,3 +1256,8 @@ def get_item_account_wise_additional_cost(purchase_document):
|
|||||||
|
|
||||||
def on_doctype_update():
|
def on_doctype_update():
|
||||||
frappe.db.add_index("Purchase Receipt", ["supplier", "is_return", "return_against"])
|
frappe.db.add_index("Purchase Receipt", ["supplier", "is_return", "return_against"])
|
||||||
|
|
||||||
|
|
||||||
|
@erpnext.allow_regional
|
||||||
|
def update_regional_gl_entries(gl_list, doc):
|
||||||
|
return
|
||||||
|
|||||||
@@ -737,6 +737,12 @@ def get_default_cost_center(args, item=None, item_group=None, brand=None, compan
|
|||||||
data = frappe.get_attr(path)(args.get("item_code"), company)
|
data = frappe.get_attr(path)(args.get("item_code"), company)
|
||||||
|
|
||||||
if data and (data.selling_cost_center or data.buying_cost_center):
|
if data and (data.selling_cost_center or data.buying_cost_center):
|
||||||
|
if args.get("customer") and data.selling_cost_center:
|
||||||
|
return data.selling_cost_center
|
||||||
|
|
||||||
|
elif args.get("supplier") and data.buying_cost_center:
|
||||||
|
return data.buying_cost_center
|
||||||
|
|
||||||
return data.selling_cost_center or data.buying_cost_center
|
return data.selling_cost_center or data.buying_cost_center
|
||||||
|
|
||||||
if not cost_center and args.get("cost_center"):
|
if not cost_center and args.get("cost_center"):
|
||||||
|
|||||||
Reference in New Issue
Block a user