---
# System prepended metadata

title: PO Adjustment - Refactor

---

# PO Adjustment - Refactor
---

+ active (coverage yg muncul dipaling depan)
+ candidate (dibuat ketika buka modal, tidak akan pernah muncul)
+ draft (coverage yg diedit user, tapi belum final)


Adj 1 - client
Adj 1a for Supplier 
  + Cov 1a CANDIDATE = false
  - Ketika readjust (buka modal) dan click "Selanjutnya" (Step 1)
    - Find or Create new Cov 1b dengan CANDIDATE = true
    - cov.find_or_intialize(shipping_address_id, adj_shipping_id)

  - Jika Step 2 - Submit
    - Cari yang CANDIDATE false (Cov 1a) dan Hapus
    - Cov 1b = Find record yang CANDIDATE true
    - Save params & Update Cov 1b CANDIDATE = false

  - Jika close, reload, refresh setelah Step 1
    - DO NOTHING

  - Ketika Reset
    - Create new Cov 1c dari Adj 1 CANDIDATE false


```ruby=
def create_coverage(param_adj_coverage, address_existing_changed)
  massal_cov_id = param_adj_coverage[:purchase_order_item_massal_coverage_id]
  cov =  po_item_coverages.find_by(id: massal_cov_id)
  po_shipping = if adj_massal.self_courier? && cov&.purchase_order_item_massal_shipping.blank?
                  po_item.purchase_order_item_massal_shippings.first
                else
                  cov.purchase_order_item_massal_shipping
                end

  # adj_shipping = if adj_massal.third_party?
  #                  adj_massal.purchase_order_adjustment_item_massal_shippings.not_default
  #                            .find_by(purchase_order_item_massal_shipping_id: po_shipping&.id) ||
  #                    adj_massal.purchase_order_adjustment_item_massal_shippings.not_default.new
  #                else
  #                  adj_massal.purchase_order_adjustment_item_massal_shippings.not_default.first ||
  #                    adj_massal.purchase_order_adjustment_item_massal_shippings.not_default.new
  #                end
  if adj_massal.third_party?
    adj_shipping = adj_massal.purchase_order_adjustment_item_massal_shippings.not_default
                             .find_by(purchase_order_item_massal_shipping_id: po_shipping&.id, candidate: true)
  else
    adj_shipping = adj_massal.purchase_order_adjustment_item_massal_shippings.not_default.where(candidate: true).first
  end

  adj_shipping = adj_massal.purchase_order_adjustment_item_massal_shippings.not_default.new if adj_shipping.blank?

  adj_shipping.purchase_order_item_massal_shipping_id = po_shipping&.id
  adj_shipping.price                                  = po_shipping&.price
  adj_shipping.courier                                = po_shipping&.courier
  adj_shipping.courier_name                           = po_shipping&.courier_name
  adj_shipping.service                                = po_shipping&.service
  adj_shipping.service_name                           = po_shipping&.service_name
  adj_shipping.shipping_method                        = adj_massal.shipping_method
  adj_shipping.speed                                  = po_shipping&.speed
  adj_shipping.speed_unit                             = po_shipping&.speed_unit
  adj_shipping.speed_label                            = po_shipping&.speed_label
  adj_shipping.candidate                              = true  # Ensure adj_shipping is candidate
  adj_shipping.save!

  saved_adj_massal_shippings << adj_shipping

  shipping_address = Phoenix::ShippingAddress.find(param_adj_coverage[:shipping_address_id]) || cov&.shipping_address

  adj_cov = adj_shipping.purchase_order_adjustment_item_massal_coverages.new
  adj_cov.purchase_order_item_massal_coverage_id       = cov&.id
  adj_cov.quantity                                     = normalize_quantity(param_adj_coverage, cov, address_existing_changed)
  adj_cov.quantity_available                           = param_adj_coverage[:quantity]
  adj_cov.shipping_address_id                          = param_adj_coverage[:shipping_address_id]
  adj_cov.shipping                                     = shipping_address.address_json
  adj_cov.previous_purchase_order_item_massal_coverage = cov
  adj_cov.candidate                                    = true
  adj_cov.save!

  adj_cov
end


def update_coverage(adj_cov, param_adj_coverage)
  shipping_address = Phoenix::ShippingAddress.find(param_adj_coverage[:shipping_address_id])
  cov = adj_cov.purchase_order_item_massal_coverage
  po_shipping = cov&.purchase_order_item_massal_shipping

  adj_shipping = if adj_massal.third_party?
                   adj_massal.purchase_order_adjustment_item_massal_shippings.not_default
                             .find_by(purchase_order_item_massal_shipping_id: po_shipping&.id) 
                 else
                   adj_massal.purchase_order_adjustment_item_massal_shippings.not_default.first 
                 end

  adj_cov.quantity                                     = normalize_quantity(param_adj_coverage, cov, false)
  adj_cov.quantity_available                           = param_adj_coverage[:quantity]
  adj_cov.shipping_address_id                          = param_adj_coverage[:shipping_address_id]
  adj_cov.shipping                                     = shipping_address.address_json
  adj_cov.previous_purchase_order_item_massal_coverage = cov
  adj_cov.candidate                                    = true
  adj_cov.save!

  if adj_shipping.present?
    adj_shipping.candidate = true
    adj_shipping.save!
  end

  adj_cov
end

def save_bulk_coverage
  params[:adjustment_coverages].each do |param_adj_coverage|
    next if no_changes?(param_adj_coverage)

    adj_cov = create_coverage(param_adj_coverage, false)

    insert_existing_addrress!(adj_cov) if shipping_address_changed?(adj_cov, param_adj_coverage)

    saved_adj_massal_coverages << adj_cov
  end
end
```

## Case: tanpa Perubahann di Step 1

#customer
Alamat 1 -> 25 => 50
Alamat 2 -> 50 => 50

# supplier
di paling luar
Alamat 1 -> 25 => 50

buka modal
step 1
Alamat 1 -> 25 => 50 (candidate: false)
Alamat 2 -> 50 => 50


setelah click next di step 1
tidak ada perubahan

setelah submit step 2
to_be_deleted = where(candidate: false)
to_be_updated = where(candidate: true)

if to_be_deleted.present? && to_be_updated.present?
  to_be_deleted.destroy_all 

  to_be_updated.update_all(candidate: false)
end

## Case: Perubahan pada alamat yg diubah customer

#customer
Alamat 1 -> 25 => 50
Alamat 2 -> 50 => 50

# supplier
di paling luar
Alamat 1 -> 25 => 50 (candidate: false)

buka modal
step 1
Alamat 1 -> 25 => 50 (id: 1, candidate: false)
Alamat 2 -> 50 => 50


setelah click next di step 1
Alamat 1 -> 25 => 60 (id: 3, candidate: true)

setelah submit step 2
to_be_deleted = where(candidate: false)
to_be_updated = where(candidate: true)

if to_be_deleted.present? && to_be_updated.present?
  to_be_deleted.destroy_all

  to_be_updated.update_all(candidate: false)
end


```ruby=
# Adjustment
# Cov asli dari PO
# Cov dari PO Adjustment (highest priority)

adj_coverages

coverages_po.each do |cov|
    adj_coverages << cov
end

# Readjustment
# Cov asli dari PO
# Cov dari PO Adjustment
# Cov dari PO Readjustment (highest priority)

coverages_po.each do |cov|
    cov = 
    
    readj_coverages << cov
end

```

## Adjustment
```ruby=
    
def adj_coverages
  @adj_coverages ||= adj_massal.purchase_order_adjustment_item_massal_coverages.not_default
                               .to_a
end

def option_coverages
  po_shipping_covs.each do |cov|
    adj_covs = adj_coverages.select { |adj| adj.purchase_order_item_massal_coverage_id == cov.id }
    adj_cov = adj_covs.detect { |adj| adj.shipping_address_id == cov.shipping_address_id }
    next if adj_cov.present? || cov.quantity_available.zero?

    adj_shipping = if adj_massal.third_party?
                     adj_massal.purchase_order_adjustment_item_massal_shippings.new
                   else
                     adj_massal.purchase_order_adjustment_item_massal_shippings.first ||
                       adj_massal.purchase_order_adjustment_item_massal_shippings.new
                   end

    adj_shipping.purchase_order_item_massal_shipping_id = cov.purchase_order_item_massal_shipping_id

    adj_cov = adj_shipping.purchase_order_adjustment_item_massal_coverages.new
    adj_cov.purchase_order_item_massal_coverage_id = cov.id

    adj_cov.quantity            = cov.quantity_available
    adj_cov.quantity_available  = cov.quantity_available
    adj_cov.shipping_address_id = cov.shipping_address_id
    adj_cov.shipping            = cov.shipping

    adj_coverages << adj_cov
  end
end

```

# Readjustment

```ruby=
def re_adj_item
  @re_adj_item ||= re_adj_massal.purchase_order_adjustment_item
end

def item_coverages
	@item_coverages ||= re_adj_item.purchase_order_item.purchase_order_item_massal_coverages
end

def re_adj_coverages
  @re_adj_coverages ||= re_adj_massal.purchase_order_adjustment_item_massal_coverages.not_default.to_a
end

def parent_re_adj_item_cov
  @parent_re_adj_item_cov ||= re_adj_item.purchase_order_adjustment_item_massal_coverages.to_a
end

def option_coverages
  [parent_re_adj_item_cov, item_coverages].flatten.each do |adj_cov|
    re_adj_cov = re_adj_coverages.detect { |adj| adj.shipping_address_id == adj_cov.shipping_address_id }
    # re_adj_cov.present? = Perubahan dari Supplier
    next if re_adj_cov.present? # Skip because re_adj_cov is already on re_adj_coverages

    # Ini adalah alamat yg belum diubah sama Supplier,
    # ini adalah adjustment alamat/qty dari Customer
    re_adj_shipping = re_adj_shipping(re_adj_massal)

		re_adj_cov = re_adj_coverage(re_adj_shipping, adj_cov)

    re_adj_coverages << re_adj_cov
  end
end

def re_adj_shipping(re_adj_massal)
  if re_adj_massal.third_party?
	  re_adj_massal.purchase_order_adjustment_item_massal_shippings.new
  else
    re_adj_massal.purchase_order_adjustment_item_massal_shippings.first
  end
end

def re_adj_coverage(re_adj_shipping, coverage)
	if coverage.is_a?(Phoenix::PurchaseOrderAdjustmentItemMassalCoverage)
		re_adj_shipping.purchase_order_item_massal_shipping_id = coverage.purchase_order_adjustment_item_massal_shipping_id
	else
		re_adj_shipping.purchase_order_item_massal_shipping_id = coverage.purchase_order_item_massal_shipping_id
	end

	re_adj_cov = re_adj_shipping.purchase_order_adjustment_item_massal_coverages.new
	
	if coverage.is_a?(Phoenix::PurchaseOrderAdjustmentItemMassalCoverage)
		re_adj_cov.purchase_order_item_massal_coverage_id = coverage.purchase_order_item_massal_coverage_id
	else
		re_adj_cov.purchase_order_item_massal_coverage_id = coverage.id
	end

	re_adj_cov.quantity            = coverage.quantity_available
	re_adj_cov.quantity_available  = coverage.quantity_available
	re_adj_cov.shipping_address_id = coverage.shipping_address_id
	re_adj_cov.shipping            = coverage.shipping
	
	re_adj_cov
end


def update_candidate!
	adj_shippings = adj_item_massal.purchase_order_adjustment_item_massal_shippings.not_default
	byebug
	# shipping
	ori_adj_shipping_ids = adj_shippings.select{ |row| row.candidate = false }.map(:id)
	Phoenix::PurchaseOrderAdjustmentItemMassalShipping.where(id: ori_adj_shipping_ids).destroy_all
	

	new_adj_shipping_ids = adj_shippings.select{ |row| row.candidate = true }.map(:id)
	Phoenix::PurchaseOrderAdjustmentItemMassalShipping.not_default
																										.where(id: new_adj_shipping_ids)
																										.update_all(candidate: false)

	#coverages
	adj_coverage_ids = new_adj_shippings.map{ |row| row.purchase_order_adjustment_item_massal_coverages.not_default.ids }
	Phoenix::PurchaseOrderAdjustmentItemMassalCoverage.where(candidate: false)
																										.where(purchase_order_adjustment_item_massal_shipping_id:
																											ori_adj_shipping_ids)
																										.destroy_all

	Phoenix::PurchaseOrderAdjustmentItemMassalCoverage.where(candidate: true)
																										.where(id: adj_coverage_ids)
																										.update_all(candidate: false)
end

# ===============================================

# Get new shippings
new_shippings = adj_item_massal.purchase_order_adjustment_item_massal_shippings
															 .includes(:purchase_order_adjustment_item_massal_coverages)
															 .not_default
															 .where(candidate: true)
															 .where.not('purchase_order_adjustment_item_massal_coverages.id': nil)
new_shipping_ids = new_shippings.pluck(:id)

# Get new coverages
new_coverages = adj_item_massal.purchase_order_adjustment_item_massal_coverages
															 .where(purchase_order_adjustment_item_massal_shipping_id: new_shipping_ids)

# Update new shippings
new_shippings.update_all(candidate: false)

# Update new coverages
new_coverages.update_all(candidate: false)

# Remove obsolete shippings
adj_item_massal.purchase_order_adjustment_item_massal_shippings.where.not(id: new_shipping_ids).destroy_all


Phoenix::PurchaseOrderAdjustmentItemMassalCoverage.not_default
																									.where(purchase_order_adjustment_item_massal_shipping_id:
																										new_shippings.pluck(:id))
																									.update_all(candidate: false)


# ==================

Coverage Option Controller

DeleteCandidateDataOfficer
MassalCoverageOptionOfficer

- Hapus data candidate (officer tersendiri)
- Render data coverage options on the fly (officer tersendiri)

Submit Coverage Controller
ItemMassalCoverageOfficer
@po_adjustment_item_massal_coverages = MassalCoverageOptionOfficer
- Simpan coverage yg berubah (ItemMassalCoverageOfficer)
- Render data coverage options on the fly (officer tersendiri)


# ========================================================

# Hapus semua coverage yg candidate = false
ori_shippings = []
new_shippings = []

adj_item_massal.purchase_order_adjustment_item_massal_shippings.not_default.each do |adj_shipping|
	if adj_shipping.candidate
		new_shippings << adj_shipping
	else
		ori_shippings << adj_shipping
	end
end

# Hapus semua coverage yg candidate = false
Phoenix::PurchaseOrderAdjustmentItemMassalCoverage.where(purchase_order_adjustment_item_massal_shipping_id:
																										ori_shippings.pluck(:id))
																									.destroy_all

# Update coverage yg candidate = true menjadi candidate = false
Phoenix::PurchaseOrderAdjustmentItemMassalCoverage.not_default
																									.where(purchase_order_adjustment_item_massal_shipping_id:
																										new_shippings.pluck(:id))
																									.update_all(candidate: false)

# Update shipping yg mempunyai at least 1 coverage dan candidate = true menjadi candidate = false
new_shippings = adj_item_massal.purchase_order_adjustment_item_massal_shippings
															 .includes(:purchase_order_adjustment_item_massal_coverages)
															 .not_default
															 .where.not('purchase_order_adjustment_item_massal_coverages.id': nil)

new_shippings.update_all('purchase_order_adjustment_item_massal_shippings.candidate': false)

# Remove obsolete shippings
adj_item_massal.purchase_order_adjustment_item_massal_shippings
							 .not_default
							 .where.not(id: new_shippings.ids)
							 .destroy_all

=============
def reset
	po_adjustment = @po_adjustment_item_massal.purchase_order_adjustment
	po_adjustment = po_adjustment.parent || po_adjustment

	officer = Phoenix::PoAdjustment::Supplier::ResetAdjustmentItemMassalOfficer.new(@po_adjustment_item_massal)
	return render_422(messages: officer.errors) unless officer.perform

	o_recalculate = Phoenix::PoAdjustment::RecalculateOfficer.new(
		po_adjustment.id,
		current_user
	)
	return render_422(messages: o_recalculate.errors) unless o_recalculate.perform

	render_200
end

```