fix: purchase invoice qty change not recalculate the consumed qty and added test cases for purchase invoice
This commit is contained in:
parent
6bbc8ec3e8
commit
110e152fa3
File diff suppressed because it is too large
Load Diff
@ -400,6 +400,7 @@ class PurchaseInvoice(BuyingController):
|
||||
# because updating ordered qty in bin depends upon updated ordered qty in PO
|
||||
if self.update_stock == 1:
|
||||
self.update_stock_ledger()
|
||||
self.set_consumed_qty_in_po()
|
||||
from erpnext.stock.doctype.serial_no.serial_no import update_serial_nos_after_submit
|
||||
update_serial_nos_after_submit(self, "items")
|
||||
|
||||
@ -998,6 +999,7 @@ class PurchaseInvoice(BuyingController):
|
||||
if self.update_stock == 1:
|
||||
self.update_stock_ledger()
|
||||
self.delete_auto_created_batches()
|
||||
self.set_consumed_qty_in_po()
|
||||
|
||||
self.make_gl_entries_on_cancel()
|
||||
|
||||
|
@ -58,6 +58,11 @@ class BuyingController(StockController, Subcontracting):
|
||||
if self.doctype in ("Purchase Receipt", "Purchase Invoice"):
|
||||
self.update_valuation_rate()
|
||||
|
||||
def onload(self):
|
||||
super(BuyingController, self).onload()
|
||||
self.set_onload("backflush_based_on", frappe.db.get_single_value('Buying Settings',
|
||||
'backflush_raw_materials_of_subcontract_based_on'))
|
||||
|
||||
def set_missing_values(self, for_validate=False):
|
||||
super(BuyingController, self).set_missing_values(for_validate)
|
||||
|
||||
|
@ -40,9 +40,10 @@ class Subcontracting():
|
||||
self.purchase_orders = [d.purchase_order for d in self.items if d.purchase_order]
|
||||
|
||||
def __identify_change_in_item_table(self):
|
||||
self.changed_name = []
|
||||
self.__changed_name = []
|
||||
self.__reference_name = []
|
||||
|
||||
if self.doctype == 'Purchase Order' or not self.get(self.raw_material_table):
|
||||
if self.doctype == 'Purchase Order' or self.is_new():
|
||||
self.set(self.raw_material_table, [])
|
||||
return
|
||||
|
||||
@ -51,17 +52,18 @@ class Subcontracting():
|
||||
return True
|
||||
|
||||
for n_row in self.items:
|
||||
self.__reference_name.append(n_row.name)
|
||||
if (n_row.name not in item_dict) or (n_row.item_code, n_row.qty) != item_dict[n_row.name]:
|
||||
self.changed_name.append(n_row.name)
|
||||
self.__changed_name.append(n_row.name)
|
||||
|
||||
if item_dict.get(n_row.name):
|
||||
del item_dict[n_row.name]
|
||||
|
||||
self.changed_name.extend(item_dict.keys())
|
||||
self.__changed_name.extend(item_dict.keys())
|
||||
|
||||
def __get_data_before_save(self):
|
||||
item_dict = {}
|
||||
if self.doctype == 'Purchase Receipt' and self._doc_before_save:
|
||||
if self.doctype in ['Purchase Receipt', 'Purchase Invoice'] and self._doc_before_save:
|
||||
for row in self._doc_before_save.get('items'):
|
||||
item_dict[row.name] = (row.item_code, row.qty)
|
||||
|
||||
@ -149,7 +151,7 @@ class Subcontracting():
|
||||
|
||||
def __get_received_items(self, doctype):
|
||||
fields = []
|
||||
self.po_field = 'purchase_order' if doctype == 'Purchase Receipt' else 'po_detail'
|
||||
self.po_field = 'purchase_order'
|
||||
|
||||
for field in ['name', self.po_field, 'parent']:
|
||||
fields.append(f'`tab{doctype} Item`.`{field}`')
|
||||
@ -161,9 +163,9 @@ class Subcontracting():
|
||||
return frappe.get_all(f'{doctype}', fields = fields, filters = filters)
|
||||
|
||||
def __get_consumed_items(self, doctype, pr_items):
|
||||
return frappe.get_all(f'{doctype} Item Supplied',
|
||||
return frappe.get_all('Purchase Receipt Item Supplied',
|
||||
fields = ['serial_no', 'rm_item_code', 'reference_name', 'batch_no', 'consumed_qty', 'main_item_code'],
|
||||
filters = {'docstatus': 1, 'reference_name': ('in', list(pr_items))})
|
||||
filters = {'docstatus': 1, 'reference_name': ('in', list(pr_items)), 'parenttype': doctype})
|
||||
|
||||
def __set_alternative_item_details(self, row):
|
||||
if row.get('original_item'):
|
||||
@ -196,13 +198,16 @@ class Subcontracting():
|
||||
return frappe.get_all('BOM', fields = fields, filters=filters, order_by = f'`tab{doctype}`.`idx`') or []
|
||||
|
||||
def __remove_changed_rows(self):
|
||||
if not self.changed_name:
|
||||
if not self.__changed_name:
|
||||
return
|
||||
|
||||
i=1
|
||||
self.set(self.raw_material_table, [])
|
||||
for d in self._doc_before_save.supplied_items:
|
||||
if d.reference_name in self.changed_name:
|
||||
if d.reference_name in self.__changed_name:
|
||||
continue
|
||||
|
||||
if (d.reference_name not in self.__reference_name):
|
||||
continue
|
||||
|
||||
d.idx = i
|
||||
@ -215,8 +220,8 @@ class Subcontracting():
|
||||
|
||||
has_supplied_items = True if self.get(self.raw_material_table) else False
|
||||
for row in self.items:
|
||||
if (self.doctype != 'Purchase Order' and ((self.changed_name and row.name not in self.changed_name)
|
||||
or (has_supplied_items and not self.changed_name))):
|
||||
if (self.doctype != 'Purchase Order' and ((self.__changed_name and row.name not in self.__changed_name)
|
||||
or (has_supplied_items and not self.__changed_name))):
|
||||
continue
|
||||
|
||||
if self.doctype == 'Purchase Order' or self.backflush_based_on == 'BOM':
|
||||
@ -305,16 +310,18 @@ class Subcontracting():
|
||||
self.available_materials[key]['serial_no'].remove(sn)
|
||||
|
||||
def set_consumed_qty_in_po(self):
|
||||
# Update consumed qty back in the purchase order
|
||||
if self.is_subcontracted != 'Yes':
|
||||
return
|
||||
|
||||
self.__get_purchase_orders()
|
||||
consumed_items, pr_items = self.__update_consumed_materials(self.doctype, return_consumed_items=True)
|
||||
|
||||
itemwise_consumed_qty = defaultdict(float)
|
||||
for row in consumed_items:
|
||||
key = (row.rm_item_code, row.main_item_code, pr_items.get(row.reference_name))
|
||||
itemwise_consumed_qty[key] += row.consumed_qty
|
||||
for doctype in ['Purchase Receipt', 'Purchase Invoice']:
|
||||
consumed_items, pr_items = self.__update_consumed_materials(doctype, return_consumed_items=True)
|
||||
|
||||
for row in consumed_items:
|
||||
key = (row.rm_item_code, row.main_item_code, pr_items.get(row.reference_name))
|
||||
itemwise_consumed_qty[key] += row.consumed_qty
|
||||
|
||||
self.__update_consumed_qty_in_po(itemwise_consumed_qty)
|
||||
|
||||
|
@ -122,10 +122,21 @@ erpnext.buying.BuyingController = class BuyingController extends erpnext.Transac
|
||||
this.set_from_product_bundle();
|
||||
}
|
||||
|
||||
this.toggle_subcontracting_fields();
|
||||
super.refresh();
|
||||
}
|
||||
},
|
||||
|
||||
supplier() {
|
||||
toggle_subcontracting_fields: function() {
|
||||
if (in_list(['Purchase Receipt', 'Purchase Invoice'], this.frm.doc.doctype)) {
|
||||
this.frm.fields_dict.supplied_items.grid.update_docfield_property('consumed_qty',
|
||||
'read_only', this.frm.doc.__onload && this.frm.doc.__onload.backflush_based_on === 'BOM');
|
||||
|
||||
this.frm.set_df_property('supplied_items', 'cannot_add_rows', 1);
|
||||
this.frm.set_df_property('supplied_items', 'cannot_delete_rows', 1);
|
||||
}
|
||||
},
|
||||
|
||||
supplier: function() {
|
||||
var me = this;
|
||||
erpnext.utils.get_party_details(this.frm, null, null, function(){
|
||||
me.apply_price_list();
|
||||
|
@ -75,15 +75,6 @@ frappe.ui.form.on("Purchase Receipt", {
|
||||
}
|
||||
|
||||
frm.events.add_custom_buttons(frm);
|
||||
frm.trigger('toggle_subcontracting_fields');
|
||||
},
|
||||
|
||||
toggle_subcontracting_fields: function(frm) {
|
||||
frm.fields_dict.supplied_items.grid.update_docfield_property('consumed_qty',
|
||||
'read_only', frm.doc.__onload && frm.doc.__onload.backflush_based_on === 'BOM');
|
||||
|
||||
frm.set_df_property('supplied_items', 'cannot_add_rows', 1);
|
||||
frm.set_df_property('supplied_items', 'cannot_delete_rows', 1);
|
||||
},
|
||||
|
||||
add_custom_buttons: function(frm) {
|
||||
|
@ -102,11 +102,6 @@ class PurchaseReceipt(BuyingController):
|
||||
if self.get("items") and self.apply_putaway_rule and not self.get("is_return"):
|
||||
apply_putaway_rule(self.doctype, self.get("items"), self.company)
|
||||
|
||||
def onload(self):
|
||||
super(PurchaseReceipt, self).onload()
|
||||
self.set_onload("backflush_based_on", frappe.db.get_single_value('Buying Settings',
|
||||
'backflush_raw_materials_of_subcontract_based_on'))
|
||||
|
||||
def validate(self):
|
||||
self.validate_posting_time()
|
||||
super(PurchaseReceipt, self).validate()
|
||||
|
@ -10,7 +10,7 @@ from erpnext.stock.doctype.item.test_item import make_item
|
||||
from erpnext.manufacturing.doctype.production_plan.test_production_plan import make_bom
|
||||
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
|
||||
from erpnext.buying.doctype.purchase_order.purchase_order import (make_rm_stock_entry,
|
||||
make_purchase_receipt, get_materials_from_supplier)
|
||||
make_purchase_receipt, make_purchase_invoice, get_materials_from_supplier)
|
||||
|
||||
class TestSubcontracting(unittest.TestCase):
|
||||
def setUp(self):
|
||||
@ -458,10 +458,273 @@ class TestSubcontracting(unittest.TestCase):
|
||||
self.assertEqual(value.qty, details.qty)
|
||||
self.assertEqual(value.batch_no, details.batch_no)
|
||||
|
||||
|
||||
def test_item_with_batch_based_on_material_transfer_for_purchase_invoice(self):
|
||||
'''
|
||||
- Set backflush based on Material Transferred for Subcontract
|
||||
- Create subcontracted PO for the item Subcontracted Item SA4 (has batch no).
|
||||
- Transfer the components from Stores to Supplier warehouse with batch no and serial nos.
|
||||
- Transfer the components in multiple batches with extra 2 qty for the batched item.
|
||||
- Create the 3 purchase receipt against the PO and split Subcontracted Items into two batches.
|
||||
- Keep the qty as 2 for Subcontracted Item in the purchase receipt.
|
||||
- In the first purchase receipt the batched raw materials will be consumed 2 extra qty.
|
||||
'''
|
||||
|
||||
set_backflush_based_on('Material Transferred for Subcontract')
|
||||
item_code = 'Subcontracted Item SA4'
|
||||
items = [{'warehouse': '_Test Warehouse - _TC', 'item_code': item_code, 'qty': 10, 'rate': 100}]
|
||||
|
||||
rm_items = [{'item_code': 'Subcontracted SRM Item 1', 'qty': 10},
|
||||
{'item_code': 'Subcontracted SRM Item 2', 'qty': 10},
|
||||
{'item_code': 'Subcontracted SRM Item 3', 'qty': 3},
|
||||
{'item_code': 'Subcontracted SRM Item 3', 'qty': 3},
|
||||
{'item_code': 'Subcontracted SRM Item 3', 'qty': 3},
|
||||
{'item_code': 'Subcontracted SRM Item 3', 'qty': 3}
|
||||
]
|
||||
|
||||
itemwise_details = make_stock_in_entry(rm_items=rm_items)
|
||||
po = create_purchase_order(rm_items = items, is_subcontracted="Yes",
|
||||
supplier_warehouse="_Test Warehouse 1 - _TC")
|
||||
|
||||
for d in rm_items:
|
||||
d['po_detail'] = po.items[0].name
|
||||
|
||||
make_stock_transfer_entry(po_no = po.name, main_item_code=item_code,
|
||||
rm_items=rm_items, itemwise_details=copy.deepcopy(itemwise_details))
|
||||
|
||||
pr1 = make_purchase_invoice(po.name)
|
||||
pr1.update_stock = 1
|
||||
pr1.items[0].qty = 2
|
||||
pr1.items[0].expense_account = 'Stock Adjustment - _TC'
|
||||
add_second_row_in_pr(pr1)
|
||||
pr1.save()
|
||||
pr1.submit()
|
||||
|
||||
for key, value in get_supplied_items(pr1).items():
|
||||
qty = 4 if key != 'Subcontracted SRM Item 3' else 6
|
||||
self.assertEqual(value.qty, qty)
|
||||
|
||||
pr1 = make_purchase_invoice(po.name)
|
||||
pr1.update_stock = 1
|
||||
pr1.items[0].expense_account = 'Stock Adjustment - _TC'
|
||||
pr1.items[0].qty = 2
|
||||
add_second_row_in_pr(pr1)
|
||||
pr1.save()
|
||||
pr1.submit()
|
||||
|
||||
for key, value in get_supplied_items(pr1).items():
|
||||
self.assertEqual(value.qty, 4)
|
||||
|
||||
pr1 = make_purchase_invoice(po.name)
|
||||
pr1.update_stock = 1
|
||||
pr1.items[0].qty = 2
|
||||
pr1.items[0].expense_account = 'Stock Adjustment - _TC'
|
||||
pr1.save()
|
||||
pr1.submit()
|
||||
|
||||
for key, value in get_supplied_items(pr1).items():
|
||||
self.assertEqual(value.qty, 2)
|
||||
|
||||
def test_partial_transfer_serial_no_components_based_on_material_transfer_for_purchase_invoice(self):
|
||||
'''
|
||||
- Set backflush based on Material Transferred for Subcontract
|
||||
- Create subcontracted PO for the item Subcontracted Item SA2.
|
||||
- Transfer the partial components from Stores to Supplier warehouse with serial nos.
|
||||
- Create partial purchase receipt against the PO and change the qty manually.
|
||||
- Transfer the remaining components from Stores to Supplier warehouse with serial nos.
|
||||
- Create purchase receipt for remaining qty against the PO and change the qty manually.
|
||||
'''
|
||||
|
||||
set_backflush_based_on('Material Transferred for Subcontract')
|
||||
item_code = 'Subcontracted Item SA2'
|
||||
items = [{'warehouse': '_Test Warehouse - _TC', 'item_code': item_code, 'qty': 10, 'rate': 100}]
|
||||
|
||||
rm_items = [{'item_code': 'Subcontracted SRM Item 2', 'qty': 5}]
|
||||
|
||||
itemwise_details = make_stock_in_entry(rm_items=rm_items)
|
||||
po = create_purchase_order(rm_items = items, is_subcontracted="Yes",
|
||||
supplier_warehouse="_Test Warehouse 1 - _TC")
|
||||
|
||||
for d in rm_items:
|
||||
d['po_detail'] = po.items[0].name
|
||||
|
||||
make_stock_transfer_entry(po_no = po.name, main_item_code=item_code,
|
||||
rm_items=rm_items, itemwise_details=copy.deepcopy(itemwise_details))
|
||||
|
||||
pr1 = make_purchase_invoice(po.name)
|
||||
pr1.update_stock = 1
|
||||
pr1.items[0].qty = 5
|
||||
pr1.items[0].expense_account = 'Stock Adjustment - _TC'
|
||||
pr1.save()
|
||||
|
||||
for key, value in get_supplied_items(pr1).items():
|
||||
details = itemwise_details.get(key)
|
||||
self.assertEqual(value.qty, 3)
|
||||
self.assertEqual(sorted(value.serial_no), sorted(details.serial_no[0:3]))
|
||||
|
||||
pr1.load_from_db()
|
||||
pr1.supplied_items[0].consumed_qty = 5
|
||||
pr1.supplied_items[0].serial_no = '\n'.join(itemwise_details[pr1.supplied_items[0].rm_item_code]['serial_no'])
|
||||
pr1.save()
|
||||
pr1.submit()
|
||||
|
||||
for key, value in get_supplied_items(pr1).items():
|
||||
details = itemwise_details.get(key)
|
||||
self.assertEqual(value.qty, details.qty)
|
||||
self.assertEqual(sorted(value.serial_no), sorted(details.serial_no))
|
||||
|
||||
itemwise_details = make_stock_in_entry(rm_items=rm_items)
|
||||
for d in rm_items:
|
||||
d['po_detail'] = po.items[0].name
|
||||
|
||||
make_stock_transfer_entry(po_no = po.name, main_item_code=item_code,
|
||||
rm_items=rm_items, itemwise_details=copy.deepcopy(itemwise_details))
|
||||
|
||||
pr1 = make_purchase_invoice(po.name)
|
||||
pr1.update_stock = 1
|
||||
pr1.items[0].expense_account = 'Stock Adjustment - _TC'
|
||||
pr1.submit()
|
||||
|
||||
for key, value in get_supplied_items(pr1).items():
|
||||
details = itemwise_details.get(key)
|
||||
self.assertEqual(value.qty, details.qty)
|
||||
self.assertEqual(sorted(value.serial_no), sorted(details.serial_no))
|
||||
|
||||
def test_partial_transfer_batch_based_on_material_transfer_for_purchase_invoice(self):
|
||||
'''
|
||||
- Set backflush based on Material Transferred for Subcontract
|
||||
- Create subcontracted PO for the item Subcontracted Item SA6.
|
||||
- Transfer the partial components from Stores to Supplier warehouse with batch.
|
||||
- Create partial purchase receipt against the PO and change the qty manually.
|
||||
- Transfer the remaining components from Stores to Supplier warehouse with batch.
|
||||
- Create purchase receipt for remaining qty against the PO and change the qty manually.
|
||||
'''
|
||||
|
||||
set_backflush_based_on('Material Transferred for Subcontract')
|
||||
item_code = 'Subcontracted Item SA6'
|
||||
items = [{'warehouse': '_Test Warehouse - _TC', 'item_code': item_code, 'qty': 10, 'rate': 100}]
|
||||
|
||||
rm_items = [{'item_code': 'Subcontracted SRM Item 3', 'qty': 5}]
|
||||
|
||||
itemwise_details = make_stock_in_entry(rm_items=rm_items)
|
||||
po = create_purchase_order(rm_items = items, is_subcontracted="Yes",
|
||||
supplier_warehouse="_Test Warehouse 1 - _TC")
|
||||
|
||||
for d in rm_items:
|
||||
d['po_detail'] = po.items[0].name
|
||||
|
||||
make_stock_transfer_entry(po_no = po.name, main_item_code=item_code,
|
||||
rm_items=rm_items, itemwise_details=copy.deepcopy(itemwise_details))
|
||||
|
||||
pr1 = make_purchase_invoice(po.name)
|
||||
pr1.update_stock = 1
|
||||
pr1.items[0].qty = 5
|
||||
pr1.items[0].expense_account = 'Stock Adjustment - _TC'
|
||||
pr1.save()
|
||||
|
||||
transferred_batch_no = ''
|
||||
for key, value in get_supplied_items(pr1).items():
|
||||
details = itemwise_details.get(key)
|
||||
self.assertEqual(value.qty, 3)
|
||||
transferred_batch_no = details.batch_no
|
||||
self.assertEqual(value.batch_no, details.batch_no)
|
||||
|
||||
pr1.load_from_db()
|
||||
pr1.supplied_items[0].consumed_qty = 5
|
||||
pr1.supplied_items[0].batch_no = list(transferred_batch_no.keys())[0]
|
||||
pr1.save()
|
||||
pr1.submit()
|
||||
|
||||
for key, value in get_supplied_items(pr1).items():
|
||||
details = itemwise_details.get(key)
|
||||
self.assertEqual(value.qty, details.qty)
|
||||
self.assertEqual(value.batch_no, details.batch_no)
|
||||
|
||||
itemwise_details = make_stock_in_entry(rm_items=rm_items)
|
||||
for d in rm_items:
|
||||
d['po_detail'] = po.items[0].name
|
||||
|
||||
make_stock_transfer_entry(po_no = po.name, main_item_code=item_code,
|
||||
rm_items=rm_items, itemwise_details=copy.deepcopy(itemwise_details))
|
||||
|
||||
pr1 = make_purchase_invoice(po.name)
|
||||
pr1.update_stock = 1
|
||||
pr1.items[0].expense_account = 'Stock Adjustment - _TC'
|
||||
pr1.submit()
|
||||
|
||||
for key, value in get_supplied_items(pr1).items():
|
||||
details = itemwise_details.get(key)
|
||||
self.assertEqual(value.qty, details.qty)
|
||||
self.assertEqual(value.batch_no, details.batch_no)
|
||||
|
||||
def test_item_with_batch_based_on_bom_for_purchase_invoice(self):
|
||||
'''
|
||||
- Set backflush based on BOM
|
||||
- Create subcontracted PO for the item Subcontracted Item SA4 (has batch no).
|
||||
- Transfer the components from Stores to Supplier warehouse with batch no and serial nos.
|
||||
- Transfer the components in multiple batches.
|
||||
- Create the 3 purchase receipt against the PO and split Subcontracted Items into two batches.
|
||||
- Keep the qty as 2 for Subcontracted Item in the purchase receipt.
|
||||
'''
|
||||
|
||||
set_backflush_based_on('BOM')
|
||||
item_code = 'Subcontracted Item SA4'
|
||||
items = [{'warehouse': '_Test Warehouse - _TC', 'item_code': item_code, 'qty': 10, 'rate': 100}]
|
||||
|
||||
rm_items = [{'item_code': 'Subcontracted SRM Item 1', 'qty': 10},
|
||||
{'item_code': 'Subcontracted SRM Item 2', 'qty': 10},
|
||||
{'item_code': 'Subcontracted SRM Item 3', 'qty': 3},
|
||||
{'item_code': 'Subcontracted SRM Item 3', 'qty': 3},
|
||||
{'item_code': 'Subcontracted SRM Item 3', 'qty': 3},
|
||||
{'item_code': 'Subcontracted SRM Item 3', 'qty': 1}
|
||||
]
|
||||
|
||||
itemwise_details = make_stock_in_entry(rm_items=rm_items)
|
||||
po = create_purchase_order(rm_items = items, is_subcontracted="Yes",
|
||||
supplier_warehouse="_Test Warehouse 1 - _TC")
|
||||
|
||||
for d in rm_items:
|
||||
d['po_detail'] = po.items[0].name
|
||||
|
||||
make_stock_transfer_entry(po_no = po.name, main_item_code=item_code,
|
||||
rm_items=rm_items, itemwise_details=copy.deepcopy(itemwise_details))
|
||||
|
||||
pr1 = make_purchase_invoice(po.name)
|
||||
pr1.update_stock = 1
|
||||
pr1.items[0].qty = 2
|
||||
pr1.items[0].expense_account = 'Stock Adjustment - _TC'
|
||||
add_second_row_in_pr(pr1)
|
||||
pr1.save()
|
||||
pr1.submit()
|
||||
|
||||
for key, value in get_supplied_items(pr1).items():
|
||||
self.assertEqual(value.qty, 4)
|
||||
|
||||
pr1 = make_purchase_invoice(po.name)
|
||||
pr1.update_stock = 1
|
||||
pr1.items[0].qty = 2
|
||||
pr1.items[0].expense_account = 'Stock Adjustment - _TC'
|
||||
add_second_row_in_pr(pr1)
|
||||
pr1.save()
|
||||
pr1.submit()
|
||||
|
||||
for key, value in get_supplied_items(pr1).items():
|
||||
self.assertEqual(value.qty, 4)
|
||||
|
||||
pr1 = make_purchase_invoice(po.name)
|
||||
pr1.update_stock = 1
|
||||
pr1.items[0].qty = 2
|
||||
pr1.items[0].expense_account = 'Stock Adjustment - _TC'
|
||||
pr1.save()
|
||||
pr1.submit()
|
||||
|
||||
for key, value in get_supplied_items(pr1).items():
|
||||
self.assertEqual(value.qty, 2)
|
||||
|
||||
def add_second_row_in_pr(pr):
|
||||
item_dict = {}
|
||||
for column in ['item_code', 'item_name', 'qty', 'uom', 'warehouse', 'stock_uom',
|
||||
'purchase_order', 'purchase_order_item', 'conversion_factor', 'rate']:
|
||||
'purchase_order', 'purchase_order_item', 'conversion_factor', 'rate', 'expense_account', 'po_detail']:
|
||||
item_dict[column] = pr.items[0].get(column)
|
||||
|
||||
pr.append('items', item_dict)
|
||||
|
Loading…
x
Reference in New Issue
Block a user