Menu

Generate receipt from Invoice not working

ghat
2007-09-01
2013-03-08
  • ghat

    ghat - 2007-09-01

    Hi,
    In AD 32 and 33 generate receipt from invoice functionality not working.
    Add few lines to to vender invoice. then complete it . Then press Generate receipt from invoice botton. Receipt is created but only one line with one product other products added to invoice is missing. In vendor invoice you get message Couldnot save changes: Invoice line. This can recreate in GardenWorld as well.
    Regards,
    Harinda

     
    • Terence Ng

      Terence Ng - 2007-09-02

      Hi Harinda,

      Yes, I have the same problem.  I have to delete this line, and press 'Create lines from' to get the lines.

      Regards,

      Terence

       
      • ghat

        ghat - 2007-09-03

        Hi Terence,
        What lines do I have to delete. Is it material receipt line or Vendor Invoice Line.
        Thank in Advance,
        Harinda

         
        • racd

          racd - 2007-12-11

          i already do some checking on the sourcecode. As i am understood the process actually successfuly copied the invoiceline to material receipe line. However problem occur when updating that invoice line.

           
    • Chris Farley

      Chris Farley - 2007-12-10

      This is a known bug. Don't push this button unless there is only one line on your invoice!

      http://sourceforge.net/tracker/index.php?func=detail&aid=1701331&group_id=176962&atid=879332

       
    • Redhuan D. Oon

      Redhuan D. Oon - 2007-12-16

      Tracing thru i arrive at the snip with Teo's mark on it :->

          /**
           * Recalculate invoice tax
           * @param oldTax true if the old C_Tax_ID should be used
           * @return true if success, false otherwise
           *
           * @author teo_sarca [ 1583825 ]
           */
          private boolean updateInvoiceTax(boolean oldTax) {
              MInvoiceTax tax = MInvoiceTax.get (this, getPrecision(), oldTax, get_TrxName());
              if (tax != null) {
                  if (!tax.calculateTaxFromLines())
                      return false;
                  if (tax.getTaxAmt().signum() != 0) {
                      if (!tax.save(get_TrxName()))
                          return false;
                  }
                  else {
                      if (!tax.is_new() && !tax.delete(false, get_TrxName()))
                          return false;
                  }
              }
              return true;
          }

      The culprit seems to be at this bottom methods -> tax.is_new and tax.delete.
      They seem to return false when executed. Perhaps Teo can throw more lite as what should be the intent.

       
    • Redhuan D. Oon

      Redhuan D. Oon - 2007-12-16

      The above snip was called during the 'Generate Receipt From Invoice' button. Which calls the public class InvoiceCreateInOut extends SvrProcess that executes <METHOD> doIt and <LINE> if (!invoiceLine.save()) that calls above when the bug occurs.

      Thus it is not sure if its a bug or a logic issue about taxation. Will continue later.

       
    • Redhuan D. Oon

      Redhuan D. Oon - 2007-12-16

      The complaint seems to be in the form of a log.warning -----------> MInvoiceTax.delete: Record processed

      This happens at !tax.delete which means that if it cannot delete it returns false on Recalculate invoice tax. Now in our case there is no tax. A quick solution that comes to mind is that this whole line got to be further qualified:

      if (!tax.is_new() && !tax.delete(false, get_TrxName()))
      return false;

      But what is it? This depends on the subject matter. You failed the process during updating of a previous Invoice (in this generate button case) where u recalculate the tax (which is correct since there is an update again) .. failed due to the 'tax not been new and not deletable'? What does this mean? Colin? Mike? NB?

       
      • Colin Rooney

        Colin Rooney - 2007-12-16

        >> What does this mean? Colin? Mike? NB?
        I read just saw you call for info ... I *think* this tax deletion is all from bug#1583825...   The purpose of which is to remove taxes not required. If for example you create an invoice (or order) add a line with product covered by Tax-A, then change the product to one covered by Tax-B ... now there is still one invoice line but both Tax-A & Tax-B tax lines.  This change was just to clean that up.  perhaps the scenario you are working with was not considered when this modification was made?
        I also have a small changed to it awaiting integration in his area http://sourceforge.net/tracker/index.php?func=detail&aid=1786103&group_id=176962&atid=879332

        colin

         
        • Colin Rooney

          Colin Rooney - 2007-12-16

          oh just read the thread and see you had already figured that all out .. sorry, red1, for telling you what you knew ... I can't really add any more.
          colin

           
    • Redhuan D. Oon

      Redhuan D. Oon - 2007-12-16

      I shut it up by introducing a true argument to the delete method as at PO.java the boolean is used for Force or Not.

      Thus it now works if its

      if (!tax.is_new() && !tax.delete(true, get_TrxName())) 
      return false;

      i.e. CHANGED TO delete{true,  INSTEAD OF delete (false,

      Again, Teo et al, is this correct in business logic?

       
    • Redhuan D. Oon

      Redhuan D. Oon - 2007-12-16

      Checked the consequence above .. see that the Receipt with multiple lines are indeed created, and the original Invoice updated at its Receipts tab. However its Tax tab details are deleted, so this is not good even if its zero tax.

      I think what is trying to do at InvoiceLine.save with the updateInvoiceTax is that if its not able to do so i.e. update the tax again then its update has failed. I think this is too implicit.

      What the is about updateInvoiceTax that makes it fail when !tax.delete? It should allow other processes to go thru and merely post the warning as above. Thus a better solution maybe not to force tax.delete and just return true even if it !tax.delete.

       
    • Redhuan D. Oon

      Redhuan D. Oon - 2007-12-16

      Now i know the reason why. It is a simple (silly) reason. The whole record was processed! See the delete(force) below:

          public boolean delete (boolean force)
          {
              CLogger.resetLast();
              if (is_new())
                  return true;
             
              int AD_Table_ID = p_info.getAD_Table_ID();
              int Record_ID = get_ID();
             
              if (!force)
              {
                  int iProcessed = get_ColumnIndex("Processed");
                  if  (iProcessed != -1)
                  {
                      Boolean processed = (Boolean)get_Value(iProcessed);
                      if (processed != null && processed.booleanValue())
                      {
                          log.warning("Record processed");    //    CannotDeleteTrx
                          log.saveError("Processed", "Processed", false);
                          return false;
                      }
                  }    //    processed
              }    //    force

       
    • Redhuan D. Oon

      Redhuan D. Oon - 2007-12-16

      Finally i have (me think) solved the mystery.

      1) Invoice (Vendor) was processed

      2) Generate Receipts from such Invoice will iterate each line to update each invoiceline with corresponding receiptline and this is where it fails.

      3) Cos it has to also recalculate the tax during update which it cannot as its 'processed' before.

      So a possible remedy can be by telling InvoiceCreateInOut that its merely putting in a non-consequence text value. This would mean a rethink on the structure of line.save itself to be more differentiated.

      So at this line there             if (!invoiceLine.save())
                      throw new IllegalArgumentException("@SaveError@ @C_InvoiceLine_ID@");

      can it just be invoiceLine.save(); without throwing it as illegal.

      Any comments if this is sound?

       
    • Redhuan D. Oon

      Redhuan D. Oon - 2007-12-16

      Nope above not sound and cant work as no receipts are created. Have to go back to looking at the updateInvoiceTax()

       
    • Redhuan D. Oon

      Redhuan D. Oon - 2007-12-16

      To rephrase the whole culprit:

                  if (tax.getTaxAmt().signum() != 0) {
                      if (!tax.save(get_TrxName()))
                          return false;
                  }
                  else {
                      if (!tax.is_new() && !tax.delete(false, get_TrxName()))
                          return false;

      where if TaxAmt == 0 (no tax) then it tries to delete, and it cannot since its processed. So this will be ok if there is TaxAmt. What is not taken care of is this loophole in such a logic where it needs to update a processed invoice and finding that it has no tax then tries to delete the tax line! This leads to a whole new argument about business logic surrounding 'processed' docs. I suggest that we control that at a higher level such as at Doc-Table 'Complete' and not at afterSave level. Thus delete(force) should not return false, or it should be forced irrespective if its master document is processed. This is to make things more atomic. I wouldnt know when i need to delete a processed document as those are just options i like to have. A rule that says 'no' has to be ascertained at a more meaningful level, ie main actor in ths case the InvoiceCreateInOut.

      So as a possible good solution is to allow delete(force) at the PO.java and that carries a big impact across, ie. any reord can be deleted if we say so at the code. There are already document level protection against deletion of a processed doc. I tested it and got 14:37:42.617 APanel.actionPerformed: Delete - 16 [11]
      14:37:42.626 ADialog.ask: DeleteRecord? - null [11]
      -----------> GridTable.saveWarning: CannotDeleteTrx -  [11]

      So for now, i suggest we allow delete(force). Comments?

       
    • Redhuan D. Oon

      Redhuan D. Oon - 2007-12-16

      Actually we need not think that deep. It is merely only at MInvoiceLine.updateInvoiceTax where we allow a force delete for tax only! :-) So no impact feared here. Just use back what i first tried:

                      if (!tax.is_new() && !tax.delete(true, get_TrxName()))
                          return false;

      It only deletes non TaxAmt. For positive TaxAmt is already returned true earlier before the ELSE stmt.

      Will submit into bug tracker for peer review.

       
    • Redhuan D. Oon

      Redhuan D. Oon - 2007-12-16

      Just read your Zero Tax needed to be tracked.. will look into it at one go..  thanks for the prompt.. might be a waste to miss it when my goggles are stuck to my head here.

      I was just tracing the above as BUG #1701331 http://sourceforge.net/tracker/index.php?func=detail&aid=1701331&group_id=176962&atid=879332

       
    • Redhuan D. Oon

      Redhuan D. Oon - 2007-12-16

      Now i think it shuld solve both issues above by just allowing an update even if taxamt is zero, thus it doesnt delete the case and thus it continue without error. Just that the lower half is now redundant. Hope others can confirm this is ok:

          private boolean updateInvoiceTax(boolean oldTax) {
              MInvoiceTax tax = MInvoiceTax.get (this, getPrecision(), oldTax, get_TrxName());
              if (tax != null) {
                  if (!tax.calculateTaxFromLines())
                      return false;
                  if (tax.getTaxAmt().signum() != 0 || tax.getTaxAmt().signum() == 0 ) { //red1 - added zero condition
                      if (!tax.save(get_TrxName()))
                          return false;
                  }
                  else {  //red1 this may become redundant

                      if (!tax.is_new() && !tax.delete(false, get_TrxName()))
                          return false;
                  }

       

Log in to post a comment.