Modify How Quotes Amount is Computed

Collapse
X
 
  • Time
  • Show
Clear All
new posts

  • Triggerz
    replied
    Thanks Yuri, I will look into this.

    Regards...

    Leave a comment:


  • yuri
    replied
    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.

    Leave a comment:


  • Triggerz
    replied
    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...


    Leave a comment:


  • Triggerz
    replied
    Hi Yuri,

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

    Thanks

    Leave a comment:


  • Triggerz
    replied
    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

    Leave a comment:


  • rabii
    commented on 's reply
    Look this is a commercial product and i highly recommend to apply what Yuri suggested to keep the logic working as expected. see comments from Yuri https://forum.espocrm.com/forum/gene...034#post125034
    Last edited by rabii; 03-02-2026, 08:19 AM.

  • yuri
    replied
    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.

    Leave a comment:


  • yuri
    replied
    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.

    Leave a comment:


  • Triggerz
    replied
    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);    
        }
    }​

    Leave a comment:


  • rabii
    replied
    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

    Leave a comment:


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

    Leave a comment:


  • rabii
    replied
    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.

    Leave a comment:


  • Triggerz
    replied
    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);
    }
    }

    Leave a comment:


  • yuri
    replied
    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.

    Leave a comment:


  • rabii
    replied
    this should help

    Leave a comment:

Working...