@@ -4529,6 +4529,286 @@ def test_lcv_for_repack_entry(self):
45294529
45304530 self .assertEqual (sles , [1500.0 , 1500.0 ])
45314531
4532+ < << << << HEAD
4533+ == == == =
4534+ @IntegrationTestCase .change_settings ("Stock Settings" , {"allow_negative_stock" : 0 })
4535+ def test_multiple_transactions_with_same_posting_datetime (self ):
4536+ from erpnext .stock .doctype .delivery_note .test_delivery_note import create_delivery_note
4537+ from erpnext .stock .stock_ledger import NegativeStockError
4538+
4539+ item_code = make_item (
4540+ "Test Item for Multiple Txn with Same Posting Datetime" , {"is_stock_item" : 1 }
4541+ ).name
4542+
4543+ pr = make_purchase_receipt (
4544+ item_code = item_code ,
4545+ qty = 100 ,
4546+ rate = 100 ,
4547+ posting_date = today (),
4548+ posting_time = "10:00:00" ,
4549+ )
4550+
4551+ create_delivery_note (
4552+ item_code = item_code ,
4553+ qty = 100 ,
4554+ rate = 100 ,
4555+ posting_date = today (),
4556+ posting_time = "10:00:00" ,
4557+ )
4558+
4559+ make_purchase_receipt (
4560+ item_code = item_code ,
4561+ qty = 150 ,
4562+ rate = 100 ,
4563+ posting_date = today (),
4564+ posting_time = "10:00:00" ,
4565+ )
4566+
4567+ self .assertRaises (NegativeStockError , pr .cancel )
4568+
4569+ @IntegrationTestCase .change_settings (
4570+ "Buying Settings" , {"set_landed_cost_based_on_purchase_invoice_rate" : 1 , "maintain_same_rate" : 0 }
4571+ )
4572+ def test_set_lcv_from_pi_created_against_po (self ):
4573+ from erpnext .buying .doctype .purchase_order .purchase_order import (
4574+ make_purchase_invoice as make_pi_against_po ,
4575+ )
4576+ from erpnext .buying .doctype .purchase_order .purchase_order import (
4577+ make_purchase_receipt as make_pr_against_po ,
4578+ )
4579+ from erpnext .buying .doctype .purchase_order .test_purchase_order import create_purchase_order
4580+
4581+ original_value = frappe .db .get_single_value ("Accounts Settings" , "over_billing_allowance" )
4582+
4583+ frappe .db .set_single_value ("Accounts Settings" , "over_billing_allowance" , 100 )
4584+
4585+ item_code = create_item ("Test Item for LCV from PI against PO" ).name
4586+
4587+ po = create_purchase_order (item_code = item_code , qty = 10 , rate = 400 )
4588+ pr = make_pr_against_po (po .name )
4589+ pr .items [0 ].qty = 5
4590+ item = frappe .copy_doc (pr .items [0 ])
4591+ item .qty = 2
4592+ pr .append ("items" , item )
4593+
4594+ item = frappe .copy_doc (pr .items [0 ])
4595+ item .qty = 3
4596+ pr .append ("items" , item )
4597+ pr .submit ()
4598+
4599+ pi = make_pi_against_po (po .name )
4600+ pi .items [0 ].rate = 500
4601+ pi .submit ()
4602+
4603+ pr .reload ()
4604+ for row in pr .items :
4605+ self .assertTrue (row .amount_difference_with_purchase_invoice )
4606+ amt_diff = 5000 * (row .qty / 10 ) - row .amount
4607+ self .assertEqual (row .amount_difference_with_purchase_invoice , amt_diff )
4608+
4609+ frappe .db .set_single_value ("Accounts Settings" , "over_billing_allowance" , original_value )
4610+
4611+ def test_purchase_return_with_and_without_return_against_rejected_qty (self ):
4612+ from erpnext .stock .doctype .purchase_receipt .purchase_receipt import (
4613+ make_purchase_return as _make_purchase_return ,
4614+ )
4615+ from erpnext .stock .doctype .purchase_receipt .purchase_receipt import (
4616+ make_purchase_return_against_rejected_warehouse ,
4617+ )
4618+
4619+ item_code = create_item ("Test Item for PR against Rejected Qty" ).name
4620+ warehouse = "_Test Warehouse - _TC"
4621+
4622+ company = frappe .db .get_value ("Warehouse" , warehouse , "company" )
4623+ rejected_wh = create_warehouse ("_Test Rejected Warehouse" , company = company )
4624+
4625+ pr = make_purchase_receipt (
4626+ item_code = item_code ,
4627+ qty = 10 ,
4628+ rejected_qty = 5 ,
4629+ rate = 100 ,
4630+ warehouse = warehouse ,
4631+ rejected_warehouse = rejected_wh ,
4632+ )
4633+
4634+ # Purchase Return against rejected qty partially
4635+ return_entry = make_purchase_return_against_rejected_warehouse (pr .name )
4636+ return_entry .items [0 ].qty = - 2
4637+ return_entry .items [0 ].received_qty = - 2
4638+ return_entry .save ()
4639+ return_entry .submit ()
4640+ pr .reload ()
4641+
4642+ # Purchase Return against rejected qty partially
4643+ return_entry = _make_purchase_return (pr .name )
4644+
4645+ self .assertEqual (return_entry .items [0 ].qty , - 10 )
4646+ self .assertEqual (return_entry .items [0 ].rejected_qty , - 3 ) # 5-2=3
4647+
4648+ return_entry .items [0 ].qty = - 8
4649+ return_entry .items [0 ].stock_qty = - 8
4650+ return_entry .items [0 ].received_qty = - 11
4651+
4652+ return_entry .save ()
4653+ return_entry .submit ()
4654+
4655+ pr .reload ()
4656+
4657+ # Purchase Return against rejected qty partially
4658+ return_entry = _make_purchase_return (pr .name )
4659+
4660+ self .assertEqual (return_entry .items [0 ].qty , - 2 )
4661+ self .assertEqual (return_entry .items [0 ].rejected_qty , 0 ) # 3-3=0
4662+
4663+ def test_do_not_use_batchwise_valuation_with_fifo (self ):
4664+ from erpnext .stock .doctype .stock_entry .test_stock_entry import make_stock_entry
4665+
4666+ item_code = make_item (
4667+ "Test Item Do Not Use Batchwise Valuation with FIFO" ,
4668+ {
4669+ "is_stock_item" : 1 ,
4670+ "has_batch_no" : 1 ,
4671+ "batch_number_series" : "BN-TESTDNUBVWF-.#####" ,
4672+ "valuation_method" : "FIFO" ,
4673+ },
4674+ ).name
4675+
4676+ doc = frappe .new_doc ("Batch" )
4677+ doc .update (
4678+ {
4679+ "batch_id" : "BN-TESTDNUBVWF-00001" ,
4680+ "item" : item_code ,
4681+ }
4682+ ).insert ()
4683+
4684+ doc .db_set ("use_batchwise_valuation" , 0 )
4685+ doc .reload ()
4686+
4687+ self .assertTrue (doc .use_batchwise_valuation == 0 )
4688+
4689+ doc = frappe .new_doc ("Batch" )
4690+ doc .update (
4691+ {
4692+ "batch_id" : "BN-TESTDNUBVWF-00002" ,
4693+ "item" : item_code ,
4694+ }
4695+ ).insert ()
4696+
4697+ self .assertTrue (doc .use_batchwise_valuation == 1 )
4698+
4699+ warehouse = "_Test Warehouse - _TC"
4700+ make_stock_entry (
4701+ item_code = item_code ,
4702+ qty = 10 ,
4703+ rate = 100 ,
4704+ target = warehouse ,
4705+ batch_no = "BN-TESTDNUBVWF-00001" ,
4706+ use_serial_batch_fields = 1 ,
4707+ )
4708+
4709+ se1 = make_stock_entry (
4710+ item_code = item_code ,
4711+ qty = 10 ,
4712+ rate = 200 ,
4713+ target = warehouse ,
4714+ batch_no = "BN-TESTDNUBVWF-00001" ,
4715+ use_serial_batch_fields = 1 ,
4716+ )
4717+
4718+ stock_queue = frappe .db .get_value (
4719+ "Stock Ledger Entry" ,
4720+ {
4721+ "item_code" : item_code ,
4722+ "warehouse" : warehouse ,
4723+ "is_cancelled" : 0 ,
4724+ "voucher_type" : "Stock Entry" ,
4725+ "voucher_no" : se1 .name ,
4726+ },
4727+ "stock_queue" ,
4728+ )
4729+
4730+ stock_queue = frappe .parse_json (stock_queue )
4731+
4732+ self .assertEqual (stock_queue , [[10 , 100.0 ], [10 , 200.0 ]])
4733+
4734+ se2 = make_stock_entry (
4735+ item_code = item_code ,
4736+ qty = 10 ,
4737+ rate = 2 ,
4738+ target = warehouse ,
4739+ batch_no = "BN-TESTDNUBVWF-00002" ,
4740+ use_serial_batch_fields = 1 ,
4741+ )
4742+
4743+ stock_queue = frappe .db .get_value (
4744+ "Stock Ledger Entry" ,
4745+ {
4746+ "item_code" : item_code ,
4747+ "warehouse" : warehouse ,
4748+ "is_cancelled" : 0 ,
4749+ "voucher_type" : "Stock Entry" ,
4750+ "voucher_no" : se2 .name ,
4751+ },
4752+ "stock_queue" ,
4753+ )
4754+
4755+ stock_queue = frappe .parse_json (stock_queue )
4756+ self .assertEqual (stock_queue , [[10 , 100.0 ], [10 , 200.0 ]])
4757+
4758+ se3 = make_stock_entry (
4759+ item_code = item_code ,
4760+ qty = 20 ,
4761+ source = warehouse ,
4762+ batch_no = "BN-TESTDNUBVWF-00001" ,
4763+ use_serial_batch_fields = 1 ,
4764+ )
4765+
4766+ ste_details = frappe .db .get_value (
4767+ "Stock Ledger Entry" ,
4768+ {
4769+ "item_code" : item_code ,
4770+ "warehouse" : warehouse ,
4771+ "is_cancelled" : 0 ,
4772+ "voucher_type" : "Stock Entry" ,
4773+ "voucher_no" : se3 .name ,
4774+ },
4775+ ["stock_queue" , "stock_value_difference" ],
4776+ as_dict = 1 ,
4777+ )
4778+
4779+ stock_queue = frappe .parse_json (ste_details .stock_queue )
4780+ self .assertEqual (stock_queue , [])
4781+ self .assertEqual (ste_details .stock_value_difference , 3000 * - 1 )
4782+
4783+ se4 = make_stock_entry (
4784+ item_code = item_code ,
4785+ qty = 20 ,
4786+ rate = 0 ,
4787+ target = warehouse ,
4788+ batch_no = "BN-TESTDNUBVWF-00001" ,
4789+ use_serial_batch_fields = 1 ,
4790+ do_not_submit = 1 ,
4791+ )
4792+
4793+ se4 .items [0 ].basic_rate = 0.0
4794+ se4 .items [0 ].allow_zero_valuation_rate = 1
4795+ se4 .submit ()
4796+
4797+ stock_queue = frappe .db .get_value (
4798+ "Stock Ledger Entry" ,
4799+ {
4800+ "item_code" : item_code ,
4801+ "warehouse" : warehouse ,
4802+ "is_cancelled" : 0 ,
4803+ "voucher_type" : "Stock Entry" ,
4804+ "voucher_no" : se4 .name ,
4805+ },
4806+ "stock_queue" ,
4807+ )
4808+
4809+ self .assertEqual (frappe .parse_json (stock_queue ), [[20 , 0.0 ]])
4810+
4811+ >> >> >> > b6312bca9c (fix : valuation rate for non batchwise valuation )
45324812
45334813def prepare_data_for_internal_transfer ():
45344814 from erpnext .accounts .doctype .sales_invoice .test_sales_invoice import create_internal_supplier
0 commit comments