Modify How Quotes Amount is Computed

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Triggerz
    Senior Member
    • May 2024
    • 161

    #1

    Modify How Quotes Amount is Computed

    Hi,

    I am looking for a way to modify how the Quotes amount is computed.

    I plan to add a custom field called additionalDiscount in the Quote entity. This discount should be added to the total discount including any discounts placed in the unit price of Quoteitems.

    I also want to add a markup field for each Quoteitems and be added to the computation as such (qty x unitprice x markup)

    I have the Sales pack and not sure if this customization is possible to achieve.

    Please help and thanks in advance...
  • rabii
    Active Community Member
    • Jun 2016
    • 1387

    #2
    this should help

    Rabii
    EspoCRM Custom Development

    🔗 Portfolio & Builds

    Comment

    • yuri
      EspoCRM product developer
      • Mar 2014
      • 9708

      #3
      Maybe consider adding an extra line item (with formula?) with the negative unit price and quantity 1. This would be the only proper way to do it. The computed total net amount should equal net amounts of all line items. Otherwise, it breaks the logic.

      Comment

      • Triggerz
        Senior Member
        • May 2024
        • 161

        #4
        Originally posted by rabii

        Thanks rabii. I tried to implement the instruction in the link but the total amount does not get updated. Not sure what I am doing wroing, please help.

        Below is the modified code in the CalculateItems.php file

        Thanks and Regards...

        Code:
        <?php
        namespace Espo\Custom\Hooks\Quote;
        
        use Espo\ORM\Entity;
        
        class CalculateItems
        {
        public static int $order = 10;
        
        public function __construct(
        // Define needed dependencies.
        ) {}
        
        public function beforeSave(Entity $entity, array $options): void
        {
        if (!$entity->has('itemList')) {
        $entity->loadItemListField();
        }
        
        $itemList = $entity->get('itemList');
        
        $amount = 0.0;
        foreach ($itemList as $item) {
        $amount += $item->quantity * $item->unitPrice * $item->factor;
        }
        
        $bulkDisk = $entity->cBulkDiscount;
        $amount = $amount - $bulkDisk;
        $entity->set('amount', $amount);
        }
        }
        ​

        Comment

        • rabii
          Active Community Member
          • Jun 2016
          • 1387

          #5
          heyTriggerz

          NB: MADE CHANGES HERE TO MEET YOUR LOGIC - ADD ADDITIONAL DISCOUNT TO THE EXISTING DISCOUNTAMOUNT

          I guess you just need to make a tiny change to get the cBulkDiscount from the entity - it should be $entity->get('cBulkDiscount') - also you don't need to recalculate the amount you are using the same code from the example at documentation which is not necessary since you just want to reduce bulkdiscount from amount - below is a simple code call the file CalculateTotalDiscount.php

          PHP Code:
          <?php
          namespace Espo\Custom\Hooks\Quote;

          use 
          Espo\ORM\Entity;

          class 
          CalculateTotalDiscount
          {
              public static 
          int $order 10;
              
              public function 
          beforeSave(Entity $entity, array $options): void
              
          {
                  if (!
          $entity->get('amount')) {
                       return;
                  }
                  
                  
          $discountAmount $entity->get('discountAmount');
                  
          $additionalDiscount $entity->get('cBulkDiscount');
                  
                  
          $totalDiscountAmount $discountAmount $additionalDiscount;
                  
                  
          $entity->set('discountAmount'$totalDiscountAmount);
              }
          }

          Also don't forget to implement a client side calculation to see numbers change on front end https://docs.espocrm.com/development...de-calculation

          Cheers
          Last edited by rabii; 02-26-2026, 08:53 AM.
          Rabii
          EspoCRM Custom Development

          🔗 Portfolio & Builds

          Comment

          • Triggerz
            Senior Member
            • May 2024
            • 161

            #6
            Thanks much rabii. Can you also share a sample code on how to implement the client side calculation? Thanks again...

            Comment

            • rabii
              Active Community Member
              • Jun 2016
              • 1387

              #7
              It should be something as below create quote-total-discount-calculation.js under client/custom/src folder

              PHP Code:
              define(['custom:quote-total-discount-calculation'], (Dep) => {

                  return class extends 
              Dep {

                      
              /**
                       * Calculate total discountamount with additional discount.
                       *
                       * @param {import('model').default} model An order.
                       */
                      
              calculate(model) {
                          
              super.calculate(model);

                          if(
              model.get('cBulkDiscount')) {
                              const 
              discountAmount model.get('discountAmount');
                              const 
              additionalDiscount model.get('cBulkDiscount');
                              
              let totalDiscountAmount discountAmount additionalDiscount;

                              
              model.set('discountAmount'totalDiscountAmount);
                          }
                      }
                  }
              }); 

              based on what you shared you wanted to add an additional discount from the field cBulkDiscount to the existing discountAmount. This will do the job both front end and backend - please make changes in the backend - see updated code above for php hook class.

              Hope this helps
              Rabii
              EspoCRM Custom Development

              🔗 Portfolio & Builds

              Comment

              • Triggerz
                Senior Member
                • May 2024
                • 161

                #8
                Hi rabii, thank you so much for your response. I have modified the PHP file based on your suggestion. I needed to keep it in the CalculateItems.php though because I added a new field in the quoteitems named cMarkup. I want to consider the cMarkup % in the computation of the amount of each quoteitems.

                However, even it I add the code below inside the foreach statement, the new quoteitem.amount is not getting reflected. I would appreciate it much if you can guide me on what I am doing wrong and how to correct it. Thanks in advance...

                Code:
                //set the new amount with markup in quoteitems
                $item->amount = $newItemAmt;
                Here is the full code of the CalculateItems.php

                Code:
                <?php
                namespace Espo\Custom\Hooks\Quote;
                
                use Espo\ORM\Entity;
                
                class CalculateItems
                {    
                    public static int $order = 10;
                
                    public function __construct(
                        // Define needed dependencies.
                    ) {}
                
                    public function beforeSave(Entity $entity, array $options): void
                    {
                        if (!$entity->has('itemList')) {
                             $entity->loadItemListField();
                        }
                
                        $itemList = $entity->get('itemList');
                
                        $amount = 0.0;
                        $newItemAmt = 0.0;
                        $newSubtotalAmt = 0.0;
                        
                        foreach ($itemList as $item) {
                            $newItemAmt = $item->quantity * $item->unitPrice * (($item->cMarkup/100)+1);
                            $amount += $newItemAmt;
                            
                            //set the new amount with markup in quoteitems
                            $item->amount = $newItemAmt;
                                        
                            //consolidate list price * qty * markup for the Subtotal
                            $newSubtotalAmt +=  $item->quantity * $item->listPrice * (($item->cMarkup/100)+1);
                        }
                                
                        // Get Total Discounts
                        $discountAmount = $entity->get('discountAmount');
                        $additionalDiscount = $entity->get('cAddldiscount');
                        $totalDiscountAmount = $discountAmount + $additionalDiscount;
                        
                        //Update SubTotal
                        $entity->set('preDiscountedAmount', $newSubtotalAmt);        
                        
                        //Update Net Amount
                        $newAmount = $amount - $additionalDiscount;
                        $entity->set('amount', $newAmount);
                                
                        //Get Shipping & Tax
                        $shippingAmt = $entity->get('shippingAmount');
                        $taxamt = $entity->get('taxAmount');
                                
                        //Update Grand Total
                        $grandGrandTotalAmount = $entity->get('grandTotalAmount');
                        $newGrandTotalAmount = $newAmount + $shippingAmt + $taxamt;
                        $entity->set('grandTotalAmount', $newGrandTotalAmount);
                        
                        //Update Total discountAmount
                        $entity->set('discountAmount', $totalDiscountAmount);    
                    }
                }​

                Comment

              • yuri
                EspoCRM product developer
                • Mar 2014
                • 9708

                #9
                If after upgrade calculations do not work, please try to remove all custom formulas and custom code concerning the entity type in question first, before reaching the customer support.

                Comment

                • yuri
                  EspoCRM product developer
                  • Mar 2014
                  • 9708

                  #10
                  I highly recommend not to amend the computed net amount (the 'amount' field) but use an additional negative line item representing discount. Otherwise, it breaks the logic.

                  Recomputing the line net amount breaks the logic as well and likely won't properly work.

                  Comment

                  • Triggerz
                    Senior Member
                    • May 2024
                    • 161

                    #11
                    Hi Yuri,

                    Apart from the bulk discount, I also need to modify the computation of each line item as I need to factor in a markup for each item thus the need to modify the calculation logic.

                    Thanks

                    Comment

                    • Triggerz
                      Senior Member
                      • May 2024
                      • 161

                      #12
                      Hi Yuri,

                      Can this bulk discount and markup feature be considered in future updates of the Sales Pack?

                      Thanks

                      Comment

                      • Triggerz
                        Senior Member
                        • May 2024
                        • 161

                        #13
                        Will be good also if the computation will be as follows:

                        Line Items (Quoteitem)
                        Unit Price = List Price * (1 + (Markup% / 100)
                        Amount = (Unit Price * Qty)
                        Discounted Amount = Amount - (Amount * Discount %)
                        Total Amount = Discounted Amount + Tax

                        In the Parent Entity (Quote)
                        Total Price = Sum of Amount in all Line Items
                        Total Line Item Discount = Sum of Discount in all Line Items
                        Additional Discount = Manual Discount Added in New Field
                        Tax = Sum of Tax in all Line Items
                        Shipping = Shipping Amount

                        Grand Total = Total Price - Total Line Item Discount - Additional Discount + Tax + Shipping

                        Thanks & Regards...


                        Comment

                        • yuri
                          EspoCRM product developer
                          • Mar 2014
                          • 9708

                          #14
                          You can achieve markup pricing with price books. A rule can add a percentage value to the base price. By assigning the needed price book to a quote (or account), you can differentiate pricing for customers. Note that the base price will be used as a list price only if the base price is less than the unit price (a markup). If the base price is greater (discount), it will be set as the list price.

                          Comment

                          • Triggerz
                            Senior Member
                            • May 2024
                            • 161

                            #15
                            Thanks Yuri, I will look into this.

                            Regards...

                            Comment

                            Working...