Class: Smerp::Quotation::ArModel::QuotationItem
- Inherits:
-
Ca::DataStore::Ar::Model
- Object
- Ca::DataStore::Ar::Model
- Smerp::Quotation::ArModel::QuotationItem
- Includes:
- ActsAsTree, TR::CondUtils, TeLogger::TeLogHelper
- Defined in:
- lib/smerp/quotation/ar_model/quotation_item.rb
Instance Method Summary collapse
- #add_ext_cal(cal) ⇒ Object
- #add_quotation_ext_cal(cal) ⇒ Object
- #balance_after_distribution ⇒ Object
- #break_children_link ⇒ Object
-
#destroy_hook ⇒ Object
Only for destroy operation.
- #distribute_to(distTo, val) ⇒ Object
- #ensure_children_link ⇒ Object
- #ext_cals ⇒ Object
- #get_item_discount(input_field = nil) ⇒ Object
- #get_item_tax ⇒ Object
- #get_qoutation_discount(input_field = nil) ⇒ Object
- #is_children_linked? ⇒ Boolean
- #is_consolidation_destination_item? ⇒ Boolean
- #is_consolidation_source_item? ⇒ Boolean
- #recalculate ⇒ Object
-
#recalculate_total_from_source_quotation_items ⇒ Object
recalculate becauase destionation line_total changed triggered before_save.
-
#recalculate_total_to_destination_quotation_items ⇒ Object
recalculate because the source item line_total changed trigger after_save.
- #total_distributed ⇒ Object
- #update_ext_cal(ecid, opts = { }) ⇒ Object
-
#update_group_total ⇒ Object
end.
- #update_related_around_save ⇒ Object
Instance Method Details
#add_ext_cal(cal) ⇒ Object
742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 |
# File 'lib/smerp/quotation/ar_model/quotation_item.rb', line 742 def add_ext_cal(cal) if self.extended_calculators.nil? res = { local: [], quotation: [] } else res = YAML.load(self.extended_calculators) end case cal when Hash ac = ExtendedCalculator.instance_from_hash(cal) when ExtendedCalculator ac = cal else raise ExtendedCalculator::ExtendedCalculatorException, "Unsupported calculator type '#{cal.class}'" end ac.owner = :quotation_item ac.owner_id = self.id if not self.new_record? res[:local] << ac self.extended_calculators = YAML.dump(res) end |
#add_quotation_ext_cal(cal) ⇒ Object
789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 |
# File 'lib/smerp/quotation/ar_model/quotation_item.rb', line 789 def add_quotation_ext_cal(cal) if self.extended_calculators.nil? res = { local: [], quotation: [] } else res = YAML.load(self.extended_calculators) end case cal when Hash ac = ExtendedCalculator.instance_from_hash(cal) when ExtendedCalculator ac = cal else raise ExtendedCalculator::ExtendedCalculatorException, "Unsupported calculator type '#{cal.class}'" end res[:quotation] << ac self.extended_calculators = YAML.dump(res) end |
#balance_after_distribution ⇒ Object
694 695 696 697 |
# File 'lib/smerp/quotation/ar_model/quotation_item.rb', line 694 def balance_after_distribution bal = self.line_total - self.total_distributed { balance_amount: bal, balance_percentage: bal.percent_of(self.line_total) } end |
#break_children_link ⇒ Object
700 701 702 703 704 705 706 707 708 709 710 711 712 713 |
# File 'lib/smerp/quotation/ar_model/quotation_item.rb', line 700 def break_children_link self.children_link = 0 # all fields updated by children shall be reset self.line_total = 0.0 self.unit_price = 0.0 self.discount = 0.0 self.line_total_after_discount = 0.0 self.tax = 0.0 self.line_total_with_tax = 0.0 self.save end |
#destroy_hook ⇒ Object
Only for destroy operation
384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 |
# File 'lib/smerp/quotation/ar_model/quotation_item.rb', line 384 def destroy_hook parent = self.parent.clone qi_dist = self.quotation_item_distributions quotation = self.quotation # record deleteion here yield if not parent.nil? if parent.is_children_linked? teLogger.debug "Parent #{parent.inspect} IS children linked" # # Children of another QuotationItem # if parent.quantity > 0 # for children item that has a parent # update parent line_total parent.line_total = parent.children.sum(:line_total) parent.consolidated_line_total = parent.children.sum(:consolidated_line_total) # update unit_price since line_total is sum of children's line_total parent.unit_price = parent.consolidated_line_total / parent.quantity parent.discount = parent.children.sum(:discount) parent.line_total_after_discount = parent.children.sum(:line_total_after_discount) parent.tax = parent.children.sum(:tax) parent.line_total_with_tax = parent.children.sum(:line_total_with_tax) #teLogger.debug "After update from children : #{self.parent.inspect}" else parent.line_total = 0.0 parent.consolidated_line_total = 0.0 parent.unit_price = 0.0 parent.discount = 0.0 parent.line_total_after_discount = 0.0 parent.tax = 0.0 parent.line_total_with_tax = 0.0 end parent.save else teLogger.debug "Parent #{parent.inspect} is NOT children linked. Skipping children update to parent." end end # if parent exist # remove the distributed figure from other record if this record is the source item qi_dist.each do |qid| citm = qid.distributed_quotation_item next if citm.nil? cal = YAML.load(qid.distribution_calculations) extRes = cal.result.clone citm.consolidated_line_total = (citm.consolidated_line_total - extRes[Smerp::Quotation::DistributionCalculator::DistributedAmount]) qid.destroy citm.source_quotation_items_link.reload citm.save end quotation.total = quotation.quotation_items.where(["parent_id is null"]).sum(:line_total) quotation.total_discount = quotation.quotation_items.where(["parent_id is null"]).sum(:discount) quotation.total_after_discount = quotation.quotation_items.where(["parent_id is null"]).sum(:line_total_after_discount) quotation.total_tax = quotation.quotation_items.where(["parent_id is null"]).sum(:tax) quotation.total_with_tax = quotation.quotation_items.where(["parent_id is null"]).sum(:line_total_with_tax) quotation.save end |
#distribute_to(distTo, val) ⇒ Object
896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 |
# File 'lib/smerp/quotation/ar_model/quotation_item.rb', line 896 def distribute_to(distTo, val) dist = QuotationItemDistribution.new dist.quotation_item = self dist.distributed_quotation_item = distTo cal = Smerp::Quotation::DistributionCalculator.new(val) cal.input_field = :consolidated_line_total dist.distribution_calculations = YAML.dump(cal.for_storage) dist.save # trigger the calculator and distribution calculations distTo.save distTo.reload end |
#ensure_children_link ⇒ Object
715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 |
# File 'lib/smerp/quotation/ar_model/quotation_item.rb', line 715 def ensure_children_link self.children_link = 1 if self.children.length > 0 and self.quantity > 0 # update from line_total self.line_total = self.children.sum(:line_total) # update unit_price since line_total is sum of children's line_total self.unit_price = self.line_total / self.quantity self.discount = self.children.sum(:discount) self.line_total_after_discount = self.children.sum(:line_total_after_discount) self.tax = self.children.sum(:tax) self.line_total_with_tax = self.children.sum(:line_total_with_tax) end self.save end |
#ext_cals ⇒ Object
812 813 814 815 816 817 818 |
# File 'lib/smerp/quotation/ar_model/quotation_item.rb', line 812 def ext_cals if self.extended_calculators.nil? [] else YAML.load(self.extended_calculators) end end |
#get_item_discount(input_field = nil) ⇒ Object
820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 |
# File 'lib/smerp/quotation/ar_model/quotation_item.rb', line 820 def get_item_discount(input_field = nil) if not_empty?(self.extended_calculators) cal = YAML.load(self.extended_calculators) found = nil cal[:local].each do |c| if c.is_a?(Smerp::Quotation::DiscountCalculator) if not_empty?(input_field) if c.input_field.to_sym == input_field.to_sym found = c break end else found = c break end end end found else nil end end |
#get_item_tax ⇒ Object
868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 |
# File 'lib/smerp/quotation/ar_model/quotation_item.rb', line 868 def get_item_tax if not_empty?(self.extended_calculators) cal = YAML.load(self.extended_calculators) found = nil cal[:local].each do |c| if c.is_a?(Smerp::Quotation::TaxCalculator) found = c break end end if found.nil? cal[:quotation].each do |c| if c.is_a?(Smerp::Quotation::TaxCalculator) found = c break end end end found else nil end end |
#get_qoutation_discount(input_field = nil) ⇒ Object
844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 |
# File 'lib/smerp/quotation/ar_model/quotation_item.rb', line 844 def get_qoutation_discount(input_field = nil) if not_empty?(self.extended_calculators) cal = YAML.load(self.extended_calculators) found = nil cal[:quotation].each do |c| if c.is_a?(Smerp::Quotation::DiscountCalculator) if not_empty?(input_field) if c.input_field.to_sym == input_field.to_sym found = c break end else found = c break end end end found else nil end end |
#is_children_linked? ⇒ Boolean
738 739 740 |
# File 'lib/smerp/quotation/ar_model/quotation_item.rb', line 738 def is_children_linked? self.children_link == 1 end |
#is_consolidation_destination_item? ⇒ Boolean
596 597 598 599 |
# File 'lib/smerp/quotation/ar_model/quotation_item.rb', line 596 def is_consolidation_destination_item? self.source_quotation_items_link.reload self.source_quotation_items_link.count > 0 end |
#is_consolidation_source_item? ⇒ Boolean
601 602 603 604 |
# File 'lib/smerp/quotation/ar_model/quotation_item.rb', line 601 def is_consolidation_source_item? self.quotation_item_distributions.reload self.quotation_item_distributions.count > 0 end |
#recalculate ⇒ Object
581 582 583 584 585 586 587 588 589 590 591 592 593 594 |
# File 'lib/smerp/quotation/ar_model/quotation_item.rb', line 581 def recalculate if self.quantity_changed? or self.unit_price_changed? self.line_total = self.quantity * self.unit_price # reset consolidated total and calculate again self.consolidated_line_total = self.line_total recalculate_total_from_source_quotation_items end if self.discount_changed? self.line_total_after_discount = self.line_total - self.discount end end |
#recalculate_total_from_source_quotation_items ⇒ Object
recalculate becauase destionation line_total changed triggered before_save
608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 |
# File 'lib/smerp/quotation/ar_model/quotation_item.rb', line 608 def recalculate_total_from_source_quotation_items #self.reload ttl = self.line_total self.source_quotation_items_link.each do |iqi| srcItm = iqi.quotation_item next if srcItm.nil? #teLogger.debug "Calculating using source item : #{srcItm.inspect}" cal = YAML.load(iqi.distribution_calculations) cal.calculate(srcItm) teLogger.debug "Distribution calculation : #{cal.result}" distAmt = cal.result[Smerp::Quotation::DistributionCalculator::DistributedAmount] ttl += distAmt srcItm.consolidated_line_total -= distAmt iqi.distribution_calculations = YAML.dump(cal.for_storage) iqi.save end self.consolidated_line_total = ttl # if there is discount calculator defined # this value shall be reset # If there is none, this value should be same as consolidated_line_total self.line_total_after_discount = ttl end |
#recalculate_total_to_destination_quotation_items ⇒ Object
recalculate because the source item line_total changed trigger after_save
645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 |
# File 'lib/smerp/quotation/ar_model/quotation_item.rb', line 645 def recalculate_total_to_destination_quotation_items #teLogger.debug "before get in : #{self.inspect}" self.quotation_item_distributions.each do |qid| citm = qid.distributed_quotation_item # for some reasons when one of the item is deleted first # but the connection is not reloaded. # Reload before coming in doesn't really solve the issue next if citm.nil? #teLogger.debug "citm : #{citm.inspect}" cal = YAML.load(qid.distribution_calculations) # get the old figure oldRes = cal.result.clone teLogger.debug "oldRes : #{oldRes}" # calculate base on #teLogger.debug "Self is : #{self.inspect}" cal.calculate(self) newRes = cal.result teLogger.debug "newRes : #{newRes}" #teLogger.debug "citm before process : #{citm.consolidated_line_total}" citm.consolidated_line_total = (citm.consolidated_line_total - oldRes[Smerp::Quotation::DistributionCalculator::DistributedAmount] + newRes[Smerp::Quotation::DistributionCalculator::DistributedAmount]) #teLogger.debug "citm after process : #{citm.consolidated_line_total}" qid.distribution_calculations = YAML.dump(cal.for_storage) qid.save # trigger other calculations citm.save end end |
#total_distributed ⇒ Object
682 683 684 685 686 687 688 689 690 691 692 |
# File 'lib/smerp/quotation/ar_model/quotation_item.rb', line 682 def total_distributed ttl = 0.0 self.quotation_item_distributions.each do |qid| cal = YAML.load(qid.distribution_calculations) ttl += cal.result[Smerp::Quotation::DistributionCalculator::DistributedAmount] end ttl end |
#update_ext_cal(ecid, opts = { }) ⇒ Object
766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 |
# File 'lib/smerp/quotation/ar_model/quotation_item.rb', line 766 def update_ext_cal(ecid, opts = { }) if not self.extended_calculators.nil? cal = YAML.load(self.extended_calculators) cal[:local].each do |c| if c.ecid == ecid opts.each do |k,v| c.send("#{k}=", v) end end end cal[:quotation].each do |c| if c.ecid == ecid opts.each do |k,v| c.send("#{k}=",v) end end end self.extended_calculators = YAML.dump(cal) end end |
#update_group_total ⇒ Object
end
370 371 372 373 374 375 376 377 378 379 380 381 |
# File 'lib/smerp/quotation/ar_model/quotation_item.rb', line 370 def update_group_total grp = self.quotation_item_group if not grp.nil? # update total grp.group_total = grp.children.sum(:group_total) + grp.quotation_items.sum(:consolidated_line_total) grp.group_discount = grp.children.sum(:group_discount) + grp.quotation_items.sum(:discount) grp.group_tax = grp.children.sum(:group_tax) + grp.quotation_items.sum(:tax) grp.save end end |
#update_related_around_save ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 |
# File 'lib/smerp/quotation/ar_model/quotation_item.rb', line 46 def if self.children.length == 0 self.line_total = self.quantity * self.unit_price if self.quantity_changed? or self.unit_price_changed? self.line_total_after_discount = self.line_total self.line_total_with_tax = self.line_total #teLogger.debug "sync consolidated #{self.inspect} to line_total #{self.line_total.to_i}" self.consolidated_line_total = self.line_total if self.new_record? #teLogger.debug "sync consolidated #{self.inspect} to line_total #{self.line_total.to_i}" else #teLogger.debug "#{self.inspect} has children : #{self.children}" end if self.quantity_changed? teLogger.debug "Quantity changed" # Change unit_price for record that has children # since unit_price is 'derived' from children's line_total if self.quantity > 0 self.unit_price = self.line_total / self.quantity else self.unit_price = 0.0 self.line_total = 0.0 end end #teLogger.debug "Before recalculate : #{self.inspect}" ## Calculate consolidated line total # Calculate line total of each item that push to this parent item if self.is_consolidation_destination_item? and not self.new_record? recalculate_total_from_source_quotation_items end #teLogger.debug "After recalculate : #{self.inspect}" # # Start trigger defined calculators # res = { local: [], quotation: [] } extCals = { local: [], quotation: [] } if not_empty?(self.extended_calculators) extCals = YAML.load(self.extended_calculators) end extCals[:local].each do |ec| teLogger.debug "Executing item calculator : #{ec.inspect}" ec.calculate(self) ec.owner_id = self.id if is_empty?(ec.owner_id) and not self.new_record? res[:local] << ec.for_storage end if self.new_record? # apply global calculator from quotation gExtCals = [] if not_empty?(self.quotation.extended_calculators) gExtCals = YAML.load(self.quotation.extended_calculators) end #cals = [] gExtCals.each do |ec| teLogger.debug "Executing item-quotation calculator : #{ec.inspect}" ec.calculate(self) ec.owner_id = self.quotation.id if is_empty?(ec.owner_id) res[:quotation] << ec.for_storage end else extCals[:quotation].each do |ec| teLogger.debug "Executing item-quotation calculator : #{ec.inspect}" ec.calculate(self) ec.owner_id = self.quotation.id if is_empty?(ec.owner_id) res[:quotation] << ec.for_storage end end # after calculate, remove item with zero params res[:local].delete_if { |c| case c.params when Smerp::Common::FinUtils::Percent c.params.value == 0 else c.params.to_i == 0 end } res[:quotation].delete_if { |c| case c.params when Smerp::Common::FinUtils::Percent c.params.value == 0 else c.params.to_i == 0 end } self.extended_calculators = YAML.dump(res) ## Calculator execution completed # cater parent changed oldParent = nil if self.parent_id_changed? and not self.parent_id_was.nil? oldParent = QuotationItem.find(self.parent_id_was) end # cater group changed oldGroup = nil if self.quotation_item_group_id_changed? and not self.quotation_item_group_id_was.nil? oldGroup = QuotationItemGroup.find(self.quotation_item_group_id) end ### # SAVE HAPPENED HERE ### yield # # AFTER SAVE # grp = self.quotation_item_group [grp, oldGroup].each do |g| if not g.nil? # update total g.group_total = g.children.sum(:group_total) + g.quotation_items.sum(:line_total) g.group_discount = g.children.sum(:group_discount) + g.quotation_items.sum(:discount) g.group_tax = g.children.sum(:group_tax) + g.quotation_items.sum(:tax) g.save end end [self.parent, oldParent].each do |pa| if not pa.nil? #pa.reload if pa.is_children_linked? teLogger.debug "Parent #{pa.inspect} IS children linked" # # Children of another QuotationItem # if pa.quantity > 0 # this parent children has changed because self # has changed its parent to other parent pa.children.reload teLogger.debug "Before setting any price : #{pa.inspect}" # for children item that has a parent # update parent line_total pa.line_total = pa.children.sum(:line_total) pa.consolidated_line_total = pa.children.sum(:consolidated_line_total) teLogger.debug "Before resetting unit price : #{pa.inspect}" # update unit_price since line_total is sum of children's line_total pa.unit_price = pa.consolidated_line_total / pa.quantity teLogger.debug "After resetting unit price : #{pa.inspect}" pa.discount = pa.children.sum(:discount) pa.line_total_after_discount = pa.children.sum(:line_total_after_discount) pa.tax = pa.children.sum(:tax) pa.line_total_with_tax = pa.children.sum(:line_total_with_tax) #teLogger.debug "After update from children : #{self.parent.inspect}" else pa.line_total = 0.0 pa.consolidated_line_total = 0.0 pa.unit_price = 0.0 pa.discount = 0.0 pa.line_total_after_discount = 0.0 pa.tax = 0.0 pa.line_total_with_tax = 0.0 end teLogger.debug "Before save parent #{pa.changes}" pa.save #pobj = QuotationItem.find(pa.id) #p pobj #pa.changes.each do |k,v| # pobj.send("#{k}=", v[1]) #end #pobj.save else teLogger.debug "Parent #{pa.inspect} is NOT children linked. Skipping children update to parent." end end # if parent exist end # calculate if I'm the source to be embedded into other items recalculate_total_to_destination_quotation_items if self.is_consolidation_source_item? #self.quotation.update_total_from_children self.quotation.total = self.quotation.quotation_items.where(["parent_id is null"]).sum(:line_total) self.quotation.total_discount = self.quotation.quotation_items.where(["parent_id is null"]).sum(:discount) self.quotation.total_after_discount = self.quotation.quotation_items.where(["parent_id is null"]).sum(:line_total_after_discount) self.quotation.total_tax = self.quotation.quotation_items.where(["parent_id is null"]).sum(:tax) self.quotation.total_with_tax = self.quotation.quotation_items.where(["parent_id is null"]).sum(:line_total_with_tax) self.quotation.save end |