Quick actions

cmd+k|ctrl+k

Navigation

Languages

Order Processing Template

Snippet info

Language

Raku

Visibility

public

Author

chacewells

Created

2017-11-09T17:53:34Z

Updated

2017-11-09T17:53:34Z

use v6;

# data exchange types
class PO-Expin-Item is rw {...}
class PO-Expin is rw {
	has Str ($.customer, $.po-ref, $.notes, $.total-value, $.total-quantity);
	has PO-Expin-Item @.items;
}
class PO-Expin-Item {
	has Str ($.po-ref, $.sku, $.description, $.value);
	has $.quantity where * ~~ Int|IntStr;
}

# domain data types
class LineItem is rw {...}
class PurchaseOrder is rw {
	has (Str $.customer, Str $.order-number, Str $.remarks, Numeric $.total-price, Numeric $.total-quantity, LineItem @.items);
}
class LineItem {
	has (Str $.order-number, Str $.part-number, Str $.description, Numeric $.price, Int $.quantity);
}

# prototype order processor does generic mapping, then delegates to customer specific sub for custom mapping
proto sub process-order (PO-Expin $*expin, |) returns PurchaseOrder {
	my PurchaseOrder $*po .= new: :customer(.customer),
		:order-number(.po-ref),
		:remarks(.notes),
		:total-price( .total-value.defined ?? .total-value.Rat !! Nil ),
		:total-quantity( .total-quantity.defined ?? .total-quantity.Int !! Nil )
		given $*expin;

	$*po.items = map { process-item($_, $*expin.customer) }, $*expin.items;

	{*} # custom order-level code

	$*po;
}

# Nordstrom Expin sub-type means customer is NORDSEA
subset NordstromExpin of PO-Expin where *.customer eq 'NORDSEA';

# dispatch to this customization if this order expin belongs to Nordstrom
# replaces {*} in proto sub process-order when the customer is NORDSEA
multi sub process-order (NordstromExpin $*expin) {
	$*po.total-quantity = $*po.items>>.quantity>>.Int.sum;
	$*po.total-price = $*po.items>>.price>>.Rat.sum;
}

subset NikeExpin of PO-Expin where *.customer eq 'NIKEPDX';
multi sub process-order (NikeExpin $*expin) {
	$*po.total-price = $*po.items>>.price>>.Rat.sum + 100.0; # $100 shop fee per order
	$*po.total-quantity = $*po.items>>.quantity>>.Int.sum;
	$*po.remarks.=uc; # all NIKE descriptions are uppercase
}

# prototype item processor does generic line item mapping, then dispatches to customer specific mapping
proto sub process-item ( PO-Expin-Item $*item, Str:D $ ) returns LineItem {
	my LineItem $*line-item .= new(
			order-number 	=> .po-ref,
			part-number 	=> .sku,
			description 	=> .description,
			price			=> .value.Rat,
			quantity		=> .quantity.Int
	) given $*item;

	{*} # custom item-level code

	$*line-item;
}

# customer specific item processing (replaces {*} in proto sub process-item when the customer is NORDSEA)
multi sub process-item (PO-Expin-Item $*item, 'NORDSEA') {
	$_ *= 10 given $*line-item.price
}

multi sub process-item (PO-Expin-Item $*item, 'NIKEPDX') {
	$*line-item.description.=uc; # all NIKE descriptions are uppercase
}

my $nordstrom-po-ref = '572242';
my PO-Expin $nordstrom-expin = new PO-Expin:
	customer => 'NORDSEA',
	:$nordstrom-po-ref,
	notes    => 'this is a purchase order',
	items    => [
		PO-Expin-Item.new(
			po-ref => $nordstrom-po-ref,
			sku => 'sku1',
			description => 'first PO item',
			value => '20',
			quantity => 5
		),
		PO-Expin-Item.new(
			po-ref => $nordstrom-po-ref,
			sku => 'sku2',
			description => 'second PO item',
			value => '35',
			quantity => 5
		),
		PO-Expin-Item.new(
			po-ref => $nordstrom-po-ref,
			sku => 'sku3',
			description => 'third PO item',
			value => '16',
			quantity => 5
		),
	];

my $nike-po-ref = 'NIKE-REF';
my PO-Expin $nike-expin = new PO-Expin:
	customer => 'NIKEPDX',
	po-ref => $nike-po-ref,
	notes    => 'this is a NIKE purchase order',
	items    => [
		PO-Expin-Item.new(
			po-ref => $nike-po-ref,
			sku => 'nike1',
			description => 'first NIKE PO item',
			value => '41',
			quantity => 11
		),
		PO-Expin-Item.new(
			po-ref => $nike-po-ref,
			sku => 'nike2',
			description => 'second NIKE PO item',
			value => '32',
			quantity => 17
		),
		PO-Expin-Item.new(
			po-ref => $nike-po-ref,
			sku => 'nike3',
			description => 'third NIKE PO item',
			value => '14',
			quantity => 502
		),
	];

my PurchaseOrder $nordstrom-po = process-order $nordstrom-expin;

$nordstrom-po.gist.say;

my PurchaseOrder $nike-po = process-order $nike-expin;

$nike-po.gist.say;
INFO