fix: Consider conversion factor for invoices

This commit is contained in:
Deepesh Garg
2020-12-24 23:50:00 +05:30
parent 573d9094bb
commit dac19cbca5
8 changed files with 99 additions and 47 deletions

View File

@@ -89,6 +89,7 @@
"po_detail", "po_detail",
"purchase_receipt", "purchase_receipt",
"pr_detail", "pr_detail",
"sales_invoice_item",
"item_weight_details", "item_weight_details",
"weight_per_unit", "weight_per_unit",
"total_weight", "total_weight",
@@ -787,12 +788,20 @@
"fieldtype": "Currency", "fieldtype": "Currency",
"label": "Outgoing Rate", "label": "Outgoing Rate",
"read_only": 1 "read_only": 1
},
{
"fieldname": "sales_invoice_item",
"fieldtype": "Data",
"label": "Sales Invoice Item",
"no_copy": 1,
"print_hide": 1,
"read_only": 1
} }
], ],
"idx": 1, "idx": 1,
"istable": 1, "istable": 1,
"links": [], "links": [],
"modified": "2020-12-23 17:30:57.458876", "modified": "2020-12-24 12:09:53.611463",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Purchase Invoice Item", "name": "Purchase Invoice Item",

View File

@@ -1628,7 +1628,8 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None):
'field_map': { 'field_map': {
source_document_warehouse_field: target_document_warehouse_field, source_document_warehouse_field: target_document_warehouse_field,
'batch_no': 'batch_no', 'batch_no': 'batch_no',
'serial_no': 'serial_no' 'serial_no': 'serial_no',
'name': 'sales_invoice_item'
} }
}) })

View File

@@ -75,6 +75,7 @@ class AccountsController(TransactionBase):
self.ensure_supplier_is_not_blocked() self.ensure_supplier_is_not_blocked()
self.validate_date_with_fiscal_year() self.validate_date_with_fiscal_year()
self.set_incoming_rate()
if self.meta.get_field("currency"): if self.meta.get_field("currency"):
self.calculate_taxes_and_totals() self.calculate_taxes_and_totals()

View File

@@ -66,8 +66,6 @@ class BuyingController(StockController):
if self.doctype in ("Purchase Receipt", "Purchase Invoice"): if self.doctype in ("Purchase Receipt", "Purchase Invoice"):
self.update_valuation_rate() self.update_valuation_rate()
self.set_out_going_rate()
def set_missing_values(self, for_validate=False): def set_missing_values(self, for_validate=False):
super(BuyingController, self).set_missing_values(for_validate) super(BuyingController, self).set_missing_values(for_validate)
@@ -220,31 +218,39 @@ class BuyingController(StockController):
else: else:
item.valuation_rate = 0.0 item.valuation_rate = 0.0
def set_out_going_rate(self): def set_incoming_rate(self):
if self.doctype not in ("Purchase Receipt", "Purchase Invoice"): if self.doctype not in ("Purchase Receipt", "Purchase Invoice"):
return return
ref_doctype = 'Delivery Note Item' if self.doctype == 'Purchase Receipt' else 'Sales Invoice Item'
items = self.get("items") items = self.get("items")
for d in items: for d in items:
if not cint(self.get("is_return")) and d.get("target_warehouse"): if not cint(self.get("is_return")) and d.get("from_warehouse"):
# Get outgoing rate based on original item cost based on valuation method # Get outgoing rate based on original item cost based on valuation method
d.outgoing_rate = get_incoming_rate({
"item_code": d.item_code,
"warehouse": d.target_warehouse,
"posting_date": self.posting_date,
"posting_time": self.posting_time,
"qty": -1 * flt(d.qty),
"serial_no": d.serial_no,
"company": self.company,
"voucher_type": self.doctype,
"voucher_no": self.name,
"allow_zero_valuation": d.get("allow_zero_valuation")
}, raise_error_if_no_rate=False)
elif self.get("return_against"): if not d.get('sales_invoice_item'):
# Get incoming rate of return entry from reference document outgoing_rate = get_incoming_rate({
# based on original item cost as per valuation method "item_code": d.item_code,
d.outgoing_rate = get_rate_for_return(self.doctype, self.name, d.item_code, self.return_against, item_row=d) "warehouse": d.from_warehouse,
"posting_date": self.posting_date,
"posting_time": self.posting_time,
"qty": -1 * flt(d.stock_qty),
"serial_no": d.serial_no,
"company": self.company,
"voucher_type": self.doctype,
"voucher_no": self.name,
"allow_zero_valuation": d.get("allow_zero_valuation")
}, raise_error_if_no_rate=False)
rate = flt(outgoing_rate * d.conversion_factor)
else:
rate = frappe.db.get_value(ref_doctype, d.get(frappe.scrub(ref_doctype)), 'rate')
if rate != d.rate:
frappe.msgprint(_("Row {0}: Item rate has been updated as per valuation rate since its an internal stock transfer")
.format(d.idx), alert=1)
d.rate = rate
def get_supplied_items_cost(self, item_row_id, reset_outgoing_rate=True): def get_supplied_items_cost(self, item_row_id, reset_outgoing_rate=True):
supplied_items_cost = 0.0 supplied_items_cost = 0.0
@@ -581,7 +587,8 @@ class BuyingController(StockController):
from_warehouse_sle = self.get_sl_entries(d, { from_warehouse_sle = self.get_sl_entries(d, {
"actual_qty": -1 * pr_qty, "actual_qty": -1 * pr_qty,
"warehouse": d.from_warehouse, "warehouse": d.from_warehouse,
"outgoing_rate": d.outgoing_rate, "outgoing_rate": d.rate,
"recalculate_rate": 1,
"dependant_sle_voucher_detail_no": d.name "dependant_sle_voucher_detail_no": d.name
}) })
@@ -592,8 +599,10 @@ class BuyingController(StockController):
"serial_no": cstr(d.serial_no).strip() "serial_no": cstr(d.serial_no).strip()
}) })
if self.is_return: if self.is_return:
outgoing_rate = get_rate_for_return(self.doctype, self.name, d.item_code, self.return_against, item_row=d)
sle.update({ sle.update({
"outgoing_rate": d.outgoing_rate, "outgoing_rate": outgoing_rate,
"recalculate_rate": 1 "recalculate_rate": 1
}) })
if d.from_warehouse: if d.from_warehouse:

View File

@@ -49,7 +49,6 @@ class SellingController(StockController):
self.set_customer_address() self.set_customer_address()
self.validate_for_duplicate_items() self.validate_for_duplicate_items()
self.validate_target_warehouse() self.validate_target_warehouse()
self.set_incoming_rate()
def set_missing_values(self, for_validate=False): def set_missing_values(self, for_validate=False):
@@ -324,7 +323,7 @@ class SellingController(StockController):
"warehouse": d.warehouse, "warehouse": d.warehouse,
"posting_date": self.posting_date, "posting_date": self.posting_date,
"posting_time": self.posting_time, "posting_time": self.posting_time,
"qty": -1*flt(d.qty), "qty": -1*flt(d.stock_qty),
"serial_no": d.serial_no, "serial_no": d.serial_no,
"company": self.company, "company": self.company,
"voucher_type": self.doctype, "voucher_type": self.doctype,
@@ -334,8 +333,9 @@ class SellingController(StockController):
# For internal transfers use incoming rate as the valuation rate # For internal transfers use incoming rate as the valuation rate
if self.get('is_internal_customer') and d.get('target_warehouse'): if self.get('is_internal_customer') and d.get('target_warehouse'):
d.rate = d.incoming_rate d.rate = flt(d.incoming_rate * d.conversion_factor)
frappe.msgprint(_("Row {0}: Item rate updated as the valuation rate since its an internal transfer").format(d.idx)) frappe.msgprint(_("Row {0}: Item rate has been updated as per valuation rate since its an internal stock transfer")
.format(d.idx), alert=1)
elif self.get("return_against"): elif self.get("return_against"):
# Get incoming rate of return entry from reference document # Get incoming rate of return entry from reference document

View File

@@ -722,7 +722,8 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None):
doctype +" Item": { doctype +" Item": {
"doctype": target_doctype + " Item", "doctype": target_doctype + " Item",
"field_map": { "field_map": {
source_document_warehouse_field: target_document_warehouse_field source_document_warehouse_field: target_document_warehouse_field,
'name': 'delivery_note_item'
}, },
"field_no_map": [ "field_no_map": [
"warehouse" "warehouse"

View File

@@ -77,6 +77,7 @@
"purchase_order_item", "purchase_order_item",
"material_request_item", "material_request_item",
"purchase_receipt_item", "purchase_receipt_item",
"delivery_note_item",
"section_break_45", "section_break_45",
"allow_zero_valuation_rate", "allow_zero_valuation_rate",
"bom", "bom",
@@ -868,12 +869,20 @@
"fieldtype": "Currency", "fieldtype": "Currency",
"label": "Outgoing Rate", "label": "Outgoing Rate",
"read_only": 1 "read_only": 1
},
{
"fieldname": "delivery_note_item",
"fieldtype": "Data",
"label": "Delivery Note Item",
"no_copy": 1,
"print_hide": 1,
"read_only": 1
} }
], ],
"idx": 1, "idx": 1,
"istable": 1, "istable": 1,
"links": [], "links": [],
"modified": "2020-12-23 17:33:19.479325", "modified": "2020-12-24 12:10:46.943722",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Stock", "module": "Stock",
"name": "Purchase Receipt Item", "name": "Purchase Receipt Item",

View File

@@ -376,6 +376,20 @@ class update_entries_after(object):
d.db_update() d.db_update()
def update_rate_on_delivery_and_sales_return(self, sle, outgoing_rate): def update_rate_on_delivery_and_sales_return(self, sle, outgoing_rate):
if frappe.db.get_value(sle.voucher_type, sle.voucher_no, 'is_internal_customer'):
frappe.db.set_value(doctype + " Item", voucher_detail_no, "rate", rate)
update_taxes_and_totals(sle.voucher_type, sle.voucher_no, outgoing_rate)
purchase_doctype = 'Purchase Invoice' if sle.voucher_type == 'Sales Invoice' else 'Purchase Receipt'
ref_field = frappe.scrub(sle.voucher_type + ' Item')
purchase_document_list = frappe.db.get_all(purchase_doctype, {'inter_company_invoice_reference':
sle.voucher_no}, ['name'], as_dict=1)
for d in purchase_document_list:
frappe.db.set_value(purchase_doctype + ' Item', {ref_field: sle.voucher_detail_no}, 'rate', outgoing_rate)
update_taxes_and_totals(purchase_doctype, d.name, outgoing_rate)
# Update item's incoming rate on transaction # Update item's incoming rate on transaction
item_code = frappe.db.get_value(sle.voucher_type + " Item", sle.voucher_detail_no, "item_code") item_code = frappe.db.get_value(sle.voucher_type + " Item", sle.voucher_detail_no, "item_code")
if item_code == sle.item_code: if item_code == sle.item_code:
@@ -386,6 +400,13 @@ class update_entries_after(object):
{"parent_detail_docname": sle.voucher_detail_no, "item_code": sle.item_code}, {"parent_detail_docname": sle.voucher_detail_no, "item_code": sle.item_code},
"incoming_rate", outgoing_rate) "incoming_rate", outgoing_rate)
def update_taxes_and_totals(doctype, docname, rate):
ref_doc = frappe.get_doc(doctype, docname)
ref_doc.calculate_taxes_and_totals()
ref_doc.db_update()
for d in ref_doc.items:
d.db_update()
def update_rate_on_purchase_receipt(self, sle, outgoing_rate): def update_rate_on_purchase_receipt(self, sle, outgoing_rate):
if frappe.db.exists(sle.voucher_type + " Item", sle.voucher_detail_no): if frappe.db.exists(sle.voucher_type + " Item", sle.voucher_detail_no):
frappe.db.set_value(sle.voucher_type + " Item", sle.voucher_detail_no, "base_net_rate", outgoing_rate) frappe.db.set_value(sle.voucher_type + " Item", sle.voucher_detail_no, "base_net_rate", outgoing_rate)
@@ -488,6 +509,7 @@ class update_entries_after(object):
else: else:
self.wh_data.valuation_rate = sle.outgoing_rate self.wh_data.valuation_rate = sle.outgoing_rate
print(self.wh_data.valuation_rate, "$#$#$#$#")
else: else:
if flt(self.wh_data.qty_after_transaction) >= 0 and sle.outgoing_rate: if flt(self.wh_data.qty_after_transaction) >= 0 and sle.outgoing_rate:
self.wh_data.valuation_rate = sle.outgoing_rate self.wh_data.valuation_rate = sle.outgoing_rate