FUNC160
:MPRF:19
:VERS:B40U
:RELE:c4
:CUST:cont
:TCPAC:td
:TCMOD:sls
:TFLNO:401
:FUNC:START
function read.sales.order.and.order.type.data()
{
	static	domain	tcorno	s.current.order

	if s.current.order <> tdsls045.orno then
		s.current.order = tdsls045.orno
		select	tdsls040.orno, tdsls040.cper, tdsls040.comp,
			tdsls040.cfrw, tdsls040.scom, tdsls040.fcrt,
			tdsls040.crte, tdsls040.ccur, tdsls040.cotp,
			tdsls040.ddat, tdsls040.odat,
			tcmcs042.reto, tcmcs042.sund, tcmcs042.casi,
			tcmcs042.stno, tcmcs042.modc,
			tcmcs002.crnd
		from	tdsls040, tcmcs002, tcmcs042
		where	tdsls040._index1 = {:tdsls041.orno}
		and	tcmcs042.cotp = tdsls040.cotp
		and	tcmcs002.ccur = tdsls040.ccur
		as set with 1 rows
		selectdo
		endselect
	endif
}

								|#143063.sn
function location.controlled.implemented()
{
	g.ilc.implemented = false
	select 	 tdilc000.iilc
	from 	 tdilc000
	as set with 1  rows
	selectdo
	endselect
	if tdilc000.iilc =  tcyesno.yes then
		g.ilc.implemented = true
	endif
}
								| # 143063.en
								| # 143063.sn
function migrate.outbound.data.to.sales.order.deliveries()
{

	|* Initialize for each sales order line sequence
	g.create.expected.delivery.line.for.tdilc401 = false
	g.no.of.outbound.advices.per.sls.sequence = 0
	g.outbound.advice.record = 0

	|* Count all outbound advices for sales order line sequence
	select	count(*):g.no.of.outbound.advices.per.sls.sequence
	from	tdilc401
	where	tdilc401._index1 = {	tdilc.koob.act.sls,
					:tdsls045.orno,
					:tdsls045.pono,
					:tdsls045.srnb}
	and	tdilc401.item = :tdsls045.item
	selectdo
	endselect

	if g.no.of.outbound.advices.per.sls.sequence >= 1 then
		|* Outbound advice present. Need to use tdilc401 data
		|* to create sales order line deliveries
		select	tdilc401.*
		from	tdilc401
		where	tdilc401._index1 = {	tdilc.koob.act.sls,
						:tdsls045.orno,
						:tdsls045.pono,
						:tdsls045.srnb}
		and	tdilc401.proc = tcyesno.yes
		and	tdilc401.item = :tdsls045.item
		selectdo
		|* Loop through all tdilc records present for the current
		|* sales order line sequence.
		|* for each delivered tdilc401 record a sales order line
		|* record on the target side is required.
		|* Per delivered outbound advice a new outbound advice
		|* sequence will be determined. 1 for the first delivered
		|* advice, 2 for the second, 3 for the third, etc.
		|* This is required because there can be a few outbound
		|* advices but the tdilc401.serb start from 100, 101,102
		|* tdilc401.serb can be set manually and is not generated
		|* by the system.
		|* The outbound advice record nr handled is stored in
		|* variable: g.outbound.advice.record
			g.outbound.advice.record = g.outbound.advice.record + 1
			dump1.and.dump2.for.migrating.outbound()
			 |* Insert an Actual Delivery record for each delivered
			 |* outbound advice.
		 	 dump.actual.delivery()			|#SP1.n
|*		 	 dump 3 | *  tdsls406 Actual delivery	|#SP1.o
		selecteos
			if g.outbound.advice.record <
				g.no.of.outbound.advices.per.sls.sequence then
				|* More not yet delivered advices present
				|* Create new sequence nr for the expected
				|* ordered qty
				g.outbound.advice.record =
						g.outbound.advice.record + 1
				g.create.expected.delivery.line.for.tdilc401 = true
				dump1.and.dump2.for.migrating.outbound()
				|* Expected advice not yet delivered thus no dump 3
			endif
		selectempty
			|* No delivered sales order advices present. But one (or
			|* more) not delivered advices present. One new sequence
			|* will be created for all the not delivered advices
			|* present. g.outbound.advice.record will be set to one
			|* done because WH and TD needs to create same sqnb.
			|* Data of the sales order line can be used.
			g.outbound.advice.record = 1
			g.create.expected.delivery.line.for.tdilc401 = true
			dump1.and.dump2.for.migrating.outbound()
			|* Expected advice not yet delivered thus no dump 3
		endselect
	else
		|* no advice present no need to use data of the
		|* Outbound advice all data is present on the sales order line.
								|#201891.sn
		g.outbound.advice.record = 1
		g.create.expected.delivery.line.for.tdilc401 = true
								|#201891.en
		dump1.and.dump2.for.migrating.outbound()
		|* Dump 3 handled in main query
 	endif
}
								|#143063.en
								|#143063.sn
function dump1.and.dump2.for.migrating.outbound()
{
	dump 1	|*  tdsls401 (sales order lines)
	|* tdsls401 (convert detail or backorder record)
	if convert.linked.order.line.data() then
		dump 2	|* tdsls402 (insert linked order line data record)
	endif
}
								|#143063.en

function domain tcbool total.line.required()
{
	|* This function determines the number of delivery lines
	domain	tcbool	l.total.line.required
	domain	tcsrnb	l.no.of.delivery.lines

	get.total.line.required.and.no.of.delivery.lines(
					l.total.line.required,
					l.no.of.delivery.lines)

	return(l.total.line.required)
}

function domain	tcsrnb	get.no.of.delivery.lines()
{
	domain	tcbool	l.total.line.required
	domain	tcsrnb	l.no.of.delivery.lines

	get.total.line.required.and.no.of.delivery.lines(
					l.total.line.required,
					l.no.of.delivery.lines)
	return(l.no.of.delivery.lines)
}

function get.total.line.required.and.no.of.delivery.lines(
			ref	domain	tcbool	o.total.line.required,
			ref	domain	tcsrnb	o.no.of.delivery.lines)
{
	|* This function determines the number of delivery lines and
	|* determines if a total line is reqiured (true/false)

	static	domain	tcorno	s.order
	static	domain	tcpono	s.position
	static	domain	tcbool	s.total.line.required
	static	domain	tcsrnb	s.no.of.delivery.lines
		domain	tcorno	l.order
		domain	tcpono	l.position
		domain	tcpono	l.sequence
		domain	tcsrnb	l.no.of.delivery.lines
		domain	tcqsl1	l.backorder.quantity

	if s.order = tdsls041.orno and
	   s.position = tdsls041.pono then
		|* Same order line -> early return
		o.total.line.required = s.total.line.required
		o.no.of.delivery.lines = s.no.of.delivery.lines
		return
	else
		s.order = tdsls041.orno
		s.position = tdsls041.pono
		s.total.line.required = false
		s.no.of.delivery.lines = 0
	endif

	select	tdsls045.srnb:l.no.of.delivery.lines,
		tdsls045.bqua:l.backorder.quantity,
		tdsls045.orno:l.order,
		tdsls045.pono:l.position,
		tdsls045.srnb:l.sequence
	from	tdsls045
	where	tdsls045._index1 = {	:tdsls041.orno,
					:tdsls041.pono}
	order by tdsls045._index1 desc
	as set with 1 rows
	selectdo
		if l.no.of.delivery.lines = 0 and
		   double.cmp(l.backorder.quantity, 0.0, 0.0001) = 0 then
		   	o.total.line.required = false
		else
			|* Backorders present in source table tdsls045 or
			|* Backorder expected in source table tdsls045
			|* then create total line in target table tdsls401
			o.total.line.required = true
		endif
	endselect
								|#143063.sn
	if g.ilc.implemented and
	   not o.total.line.required and
	   g.no.of.outbound.advices.per.sls.sequence > 1 and
	   tdsls045.dqua <> 0 then
		|* If only not delivered advice are present no need for a
		|* total line.
		|* If an advice is delivered then dqua is filled on the sales
		|* order line.
		|* Multiple outbound advice leads to multiple sales order
		|* delivery lines and thus requires a total.
		o.total.line.required = true
	endif
								|#143063.en
	o.no.of.delivery.lines = l.no.of.delivery.lines
	s.total.line.required = o.total.line.required
	s.no.of.delivery.lines = o.no.of.delivery.lines
}

function get.total.line.values()
{
	domain	tcbool	l.order.not.complete.delivered
	domain tcstno	l.stno.4223

	domain	tcqsl1	l.delivered.quantity
	domain	tcqsl1	l.ordered.quantity
	domain	tcamnt	l.order.amount
	domain	tcpmsk	l.procedure.mask
	domain	tcqsl1	l.backorder.quantity
	domain	tcdate	l.delivery.date
	domain	tcamnt	l.line.discount.amnt
	domain	tcamnt	l.order.discount.amnt
	domain	tcorno	l.order
	domain	tcpono	l.position
	domain	tcpono	l.sequence

	g.total.oamt = 0.0
	g.total.damt = 0.0
	g.total.amld = 0.0
	g.total.amod = 0.0
	g.total.qoor = 0.0
	g.total.qidl = 0.0
	g.total.qbbo = 0.0
	g.total.dldt = 0
	l.order.not.complete.delivered = false

	l.delivered.quantity 	= 0.0
	l.ordered.quantity   	= 0.0
	l.order.amount       	= 0.0
	l.procedure.mask     	= ""
	l.backorder.quantity 	= 0.0
	l.delivery.date      	= 0
	l.line.discount.amnt	= 0.0
	l.order.discount.amnt	= 0.0

	select	tdsls045.dqua:l.delivered.quantity,
		tdsls045.oqua:l.ordered.quantity,
		tdsls045.amnt:l.order.amount,
		tdsls045.pmsk:l.procedure.mask,
		tdsls045.bqua:l.backorder.quantity,
		tdsls045.ddat:l.delivery.date,
		tdsls045.ldam:l.line.discount.amnt,
		tdsls045.odam:l.order.discount.amnt,
		tdsls045.orno:l.order,
		tdsls045.pono:l.position,
		tdsls045.srnb:l.sequence
	from	tdsls045
	where	tdsls045._index1 = {	:tdsls041.orno,
					:tdsls041.pono}
	order by tdsls045._index1
	selectdo
|		if tdsls045.ddat = 0 then			|#202399.o
		if l.delivery.date = 0 then			|#202399.n
			|* Check if the backorder line should be taken into
			|* account. This is true if the line is not delivered
			|* and process delivered sales order is yes.
			|* Else the sales order line can be skipped for
			|* calculating total values. get next record.
			tdsls0014.session.status("tdsls4223m000", l.stno.4223)
			if l.procedure.mask(l.stno.4223;1) = "e" then
				continue
			endif
			l.order.not.complete.delivered = true
			g.total.dldt = 0
			g.total.qbbo = l.backorder.quantity
			g.total.qoor = g.total.qoor + l.ordered.quantity
			g.total.oamt = g.total.oamt + l.order.amount
			g.total.amld = g.total.amld + l.line.discount.amnt
			g.total.amod = g.total.amod + l.order.discount.amnt
		else
			if not l.order.not.complete.delivered and
			   l.delivery.date > g.total.dldt then
				g.total.dldt = l.delivery.date
			endif
|			if backorder.confirmed() then		|#202399.o
								|#202399.sn
			|* Bind variables passed for evaluation in function.
			if backorder.confirmed(l.backorder.quantity,
					       l.sequence) then
								|#202399.en
				|* When the last sales order line is delivered
				|* but the backorder qty not yet confirmed then
				|* the ordered qty is based upon the ordered
				|* quantity of the sales order line. If the
				|* Back order is confirmed then the ordered qty
				|* is based upon the delivered and backorder
				|* quantity.
				g.total.qoor = g.total.qoor +
|#800-143070.so				       l.delivered.quantity +
|#800-143070.eo				       l.backorder.quantity
|#800-143070.sn
					       l.delivered.quantity
|#800-143070.en
			else
				g.total.qoor = g.total.qoor + l.ordered.quantity
								|#800-143063.sn
				g.total.qbbo = g.total.qbbo + l.backorder.quantity

								|#800-143063.en
			endif
			g.total.oamt = g.total.oamt + l.order.amount
			g.total.damt = g.total.damt + l.order.amount
			g.total.amld = g.total.amld + l.line.discount.amnt
			g.total.amod = g.total.amod + l.order.discount.amnt
		endif
		g.total.qidl = g.total.qidl + l.delivered.quantity
	endselect
}

function domain tcbool convert.linked.order.line.data()
{
	static	domain	tcorno	s.order
	static	domain	tcpono	s.position
	static	domain	tcbool	s.linked.data

	if s.order = tdsls045.orno and
	   s.position = tdsls045.pono then
		return(s.linked.data)
	else
		s.order = tdsls045.orno
		s.position = tdsls045.pono
		s.linked.data = true
	endif

	if tdsls041.porn = 0 and
	   tdsls041.qono = 0 and
	   tdsls045.ddat = 0 and
	   tdsls045.torn = 0 and
	   not purchase.advice.present() then
		s.linked.data = false
	endif
 	return(s.linked.data)
}

function domain tcbool purchase.advice.present()
{
	|* This function checks if there is a purchase order advice.
	|* If an advice is present then linked order line data needs to be
	|* created.

	domain	tcorno	l.planned.purchase.order
	domain	tccwar	l.planned.purchase.order.cwar	fixed

 	l.planned.purchase.order = 0

 	read.purchase.order.advice(
					tdsls045.orno,
					tdsls045.pono,
					l.planned.purchase.order,
					l.planned.purchase.order.cwar)

 	if l.planned.purchase.order <> 0 then
 		return(true)
 	endif

	return(false)
}

function domain bcorno get.purchase.order.advice()
{
	|* The purchase order advice order number is retrieved and coverted
	|* according to the convert number rules.

		domain	tcorno	l.planned.purchase.order
		domain	tccwar	l.planned.purchase.order.cwar		fixed
	static	domain	tcorno	s.planned.purchase.order
	static	domain	bcorno	s.converted.purchase.order.advice	fixed

 	l.planned.purchase.order = 0

  	read.purchase.order.advice(
					tdsls045.orno,
					tdsls045.pono,
					l.planned.purchase.order,
					l.planned.purchase.order.cwar)

	if l.planned.purchase.order = s.planned.purchase.order then
		return(s.converted.purchase.order.advice)
	endif

	s.planned.purchase.order = l.planned.purchase.order
 	if l.planned.purchase.order = 0 then
 		s.converted.purchase.order.advice = ""
 	else
		s.converted.purchase.order.advice = convert.number(
						       bcckon.pur.advice,
						       l.planned.purchase.order)
	endif
	return(s.converted.purchase.order.advice)
}

function read.purchase.order.advice(
			domain	tcorno	i.sales.order,
			domain	tcpono	i.sales.position,
		ref	domain	tcorno	o.planned.purchase.order,
		ref	domain	tccwar	o.planned.purchase.order.cwar)
{
	static	domain	tcorno	s.order
	static	domain	tcpono	s.position
	static	domain	tcorno	s.planned.purchase.order
	static	domain	tccwar	s.planned.purchase.order.cwar	fixed

	if s.order = i.sales.order and
	   s.position = i.sales.position then
		o.planned.purchase.order = s.planned.purchase.order
		o.planned.purchase.order.cwar = s.planned.purchase.order.cwar
		return
	else
		s.order = i.sales.order
		s.position = i.sales.position
		s.planned.purchase.order = 0
		s.planned.purchase.order.cwar = ""
	endif

	select  tdinv310.orno:s.planned.purchase.order,
	 	 tdinv310.cwar:s.planned.purchase.order.cwar
	from 	 tdinv310
	where	 tdinv310._index5 = {:i.sales.order, :i.sales.position}
	as set with 1 rows
	selectdo
	selectempty
	 	s.planned.purchase.order = 0
		s.planned.purchase.order.cwar = ""
	endselect
}

function domain	bcorno	get.order.number()
{
	static	domain	tcorno	s.old.order
	static	domain	bcorno	s.new.order

	if s.old.order <> tdsls045.orno then
		s.old.order = tdsls045.orno
		s.new.order = convert.number(bcckon.act.sls, tdsls045.orno)
	endif
	return(s.new.order)
}

|								|#143063.so
|function domain tcpono get.order.line.sequence()
|{
|	if g.total.line then
|		|* If total line then insert sequence 0
|		return(0)
|	endif
|
|	if not total.line.required() then
|		|* If no backorders are present or expected then insert a
|		|* detail with sequence 0
|		return(tdsls045.srnb)
|	endif
|	|* In all other cases backorders are present and an extra total with
|	|* sequence 0 needs to be inserted. So convert sequence 0 to sequence 1,
|	|*  sequence 1 to sequence 2 etc.
|	return(tdsls045.srnb+1)
|	}
|								|#143063.eo
								|#143063.sn
function domain tcpono get.order.line.sequence()
{
	if g.total.line then
		|* If total line then insert sequence 0
		return(0)
	endif

	if g.ilc.implemented then
		if not total.line.required() then
			|* If only one delivered tdilc401 record is present for
			|* one sales order line sequence then no total required
			|* and the new target seqeuce can be the same as the
			|* source sequence number.
		 	|* If no backorders are present or expected then insert
			|* a detail with sequence 0
			return(tdsls045.srnb)
		endif

		if total.line.required() then
			|* For ILC check tdilc401 for multiple records. For each
			|* delivered tdilc401 record a sales order line delivery
			|* is required. Determine target sequence number using
			|* the tdilc401.serb field
			|* Target sequence has 4 positions: positions 1 and 2
			|* will be used for the sales sequence and the position
			|* 3 and 4 will be used for the outbound sequence number
			|* Assume no more then 99 sales sequences and 99
			|* delivered outbound advices per sales order line.
			return((tdsls045.srnb+1)*100 + g.outbound.advice.record)
		endif
	endif

	|* For non ILC
	if not total.line.required() then
		|* If no backorders are present or expected then insert a
		|* detail with sequence 0
		return(tdsls045.srnb)
	endif
	|* In all other cases backorders are present and an extra total with
	|* sequence 0 needs to be inserted. So convert sequence 0 to sequence 1,
	|*  sequence 1 to sequence 2 etc.
	return(tdsls045.srnb+1)
}
								|#143063.en

function long get.order.line.type()
{
	if g.total.line then
		return(target(tdgen.oltp.total))
	endif

	if tdsls045.srnb > 0 then
		return(target(tdgen.oltp.backorder))
	endif

	|* In all other cases it is just a detail line
	return(target(tdgen.oltp.detail))
}

function long get.delivery.type()
{
	if g.total.line then
		return(target(tdsls.dltp.not.applicable))
	endif

	if tdsls041.drct = tcyesno.yes then
		return(target(tdsls.dltp.direct.delivery))
	endif
	if purchase.advice.present() or
	   tdsls041.porn <> 0 then
		return(target(tdsls.dltp.cross.docking))
	endif

	read.item.data()
	if g.item.type <> tckitm.purchase and
	   g.item.type <> tckitm.manufacture and
	   g.item.type <> tckitm.generic then
		return(target(tdsls.dltp.not.applicable))
	endif
	return(target(tdsls.dltp.warehousing))
}

function read.item.data()
{
	static	domain	tcitem	s.item	fixed

	if s.item <> tdsls045.item then
		s.item = tdsls045.item
		select	tiitm001.kitm:g.item.type,
			tiitm001.stva:g.inventory.valuation
		from	tiitm001
		where	tiitm001._index1 = {	:tdsls045.item}
		as set with 1 rows
		selectdo
		endselect
	endif
}

function domain	bcstc.bpid tdsls401.get.business.partner()
{
	static	domain	tccuno		s.old.customer		fixed
	static	domain	bcstc.bpid	s.new.business.partner	fixed

	if s.old.customer <> tdsls045.cuno then
		s.old.customer = tdsls045.cuno
		s.new.business.partner = get.business.partner.code(
					tdsls045.cuno,
					bcstc.orgn.cuno,
					g.error.message)
	endif
	return(s.new.business.partner)
}

function domain	bccadr get.ship.to.address()
{
	static	domain	tcorno	s.order
	static	domain	tcpono	s.position
	static	domain	bccadr	s.new.address.code	fixed

	if s.order = tdsls045.orno and
	   s.position = tdsls045.pono then
       		return(s.new.address.code)
       	else
	       	s.order = tdsls045.orno

	       	s.position = tdsls045.pono
		s.new.address.code = ""
       	endif
        s.new.address.code = convert.sales.address(
        				tdsls041.cdel,
        				tdsls045.cuno,
        				tdsls045.orno,
        				tdsls045.pono,
        				0)
        return(s.new.address.code)
}

function domain bcstc.ccnt get.ship.to.contact()
{
|* Expl	: This function converts the Sales Order Contact. If the Sales
|*	  contact on the source side is empty then the function returns empty.
|* Pre	: na
|* Post	: na
|* Input	: i.source.customer -> Customer of the order
|*	  i.source.contact -> Tobe converted (source) contact
|* Output: na
|* Return: Converted Sales contact

		domain 	bcstc.keys 	l.contact.key		fixed
	static	domain	bcstc.ccnt	s.converted.contact	fixed
	static	domain	tccuno		s.old.customer		fixed
	static	domain	tdsmi.cper 	s.old.contact		fixed

	if s.old.customer = tdsls045.cuno and
	   s.old.contact = tdsls040.cper then
		return(s.converted.contact)
	else
		s.old.customer = tdsls045.cuno
		s.old.contact = tdsls040.cper
		s.converted.contact = ""
		l.contact.key = ""
	endif

	if not isspace(tdsls040.cper) then
		l.contact.key(1;6) = tdsls045.cuno
		l.contact.key(7;6) = tdsls040.cper


		if get.cross.reference.for.contact.code(
					"tdsmi120",
					l.contact.key,
					g.error.message) = 0 then
			s.converted.contact = bcstc005.ccnt
		endif
	endif
	return(s.converted.contact)
}

function domain bcrtyp get.sales.exchange.rate.type()
{
	static	domain	bcrtyp		s.rate.type	fixed

	if not isspace(s.rate.type) then
		return(s.rate.type)
	endif

	g.ret = get.exchange.rate.type(
		"SLS",
		g.error.message)
	s.rate.type = bcstc011.rtyp

	return(s.rate.type)
}

|function domain tcitem get.item ()				|#202933.o
function domain bcitem get.item ()				|#202933.n
{
 	 if tdsls041.opol = tcittc.customized then
 	 	 return ( segment.item.code (
 	 	 	 	 tdsls045.item,
 	 	 	 	 get.project(tdsls045.cprj)))
 	 else
 	 	 return ( segment.item.code (
 	 	 	 	 tdsls045.item,
 	 	 	 	 "" ))
 	 endif
}

function domain	bccpvl get.product.variant()
{
	static	domain	tccpva	s.old.product.variant	fixed
	static	domain	bccpvl	s.new.product.variant
			long	l.ret

	if isspace(tdsls041.cpva) or
	   g.total.line then
		return(0)
	endif

	if s.old.product.variant <> tdsls041.cpva then
		l.ret = get.new.product.variant(
				tdsls041.cpva,
				g.error.message)
		s.new.product.variant = bcsti001.cpvl
	endif
	return(s.new.product.variant)
}

function long	get.make.customized()
{
	if g.total.line then
		return(target(tcyesno.no))
	endif

	if tdsls041.opol = tcittc.make.customized then
		return(target(tcyesno.yes))
	endif
	return(target(tcyesno.no))
}

								|#Sp1.sn
function long	get.order.line.is.blocked()
{
	|* Blocked flag is not set for total lines
	if g.total.line then
		return(target(tcyesno.no))
	endif

	|* If the order is blocked all lines for this order will be blocked.
	if tdsls040.bkyn = tcyesno.yes then
		return(target(tcyesno.yes))
	endif
	return(target(tcyesno.no))
}
								|#Sp1.en


|*****************************************
|* Determine date fields
|*****************************************
function domain tcdate get.planned.delivery.date.field()
{
	|* If the order is to be shipped completely then the planned delivery
	|* date of the line must be equal to the planned delivery date of the
	|* sales order header (all lines must have the same delivery date)
	|* If the planned delivery date is not set then initialize the
	|* planned delivery date with the order date.
	|* if the planned delivery date is before the order date then set the
	|* planned delivery date equal to the order date.
	|* the function returns the source date field and still needs to be
	|* converted to UTC date.
	if tdsls040.scom = tcyesno.yes then
		return(tdsls040.ddat)
	endif

	if tdsls041.ddta > 0 and
	   tdsls041.ddta > tdsls041.odat then
		return(tdsls041.ddta)
	else
		return(tdsls041.odat)
	endif
}

|function domain tcdate get.actual.delivery.date.field()
|{
|	|* the function returns the source date field and still needs to be
|	|* converted to UTC date.
|	if g.total.line then
|		return(g.total.dldt)
|	else
||		return(tdsls045.ddat)
|		return(get.planned.delivery.date.field())
|	endif
|}

|								|#143063.so
|function string get.actual.delivery.date()
|{
|	if g.total.line then
|		return(utc(g.total.dldt, 0))
|	else
|		return(utc(tdsls045.ddat, 0))
|	endif
|}
|								|#143063.eo
|								|#143063.so
|function string get.actual.delivery.date()
|{
|	if g.total.line then
|		if g.ilc.implemented and
|	   	   g.no.of.outbound.advices.per.sls.sequence > 1 then
|	   	   	|* leave delivery date empty.
|	   	   	|* To determine if the delivery date must for a total
|	   	   	|* line must be filled and how in an ILC situation
|	   	   	|* is a lot of coding. Can be done when customers
|	   	   	|* request for it.
|			return(utc(0,0))
|		else
|			return(get.utc(g.total.dldt))
|		endif
|	else
|		if g.create.expected.delivery.line.for.tdilc401 then
|			|* For the expected sales order delivery line the
|			|* actual delivery date is always zero
|			return(utc(0,0))
|		else
|			return(get.utc(tdsls045.ddat))
|		endif
|	endif
|}
|								|#143063.eo
								|#143063.sn
function string get.actual.delivery.date()
{
	|**************************************
	|* Total line and ILC Implemented
	|**************************************
	if g.total.line and g.ilc.implemented then
		if g.create.expected.delivery.line.for.tdilc401 then
			|* If an expected sales order delivery line is created
			|* then the total line is not fully delivered and thus
			|* the delivery date is set to zero
			return(utc(0,0))
		endif

		|* For all other deliveries set the delivery date equal to the
		|* latest delivery date of the sales order lines (source value).
   	   	|* To determine if the delivery date for a total line must be
   	   	|* filled and how in an ILC situation based upon the outbound
   	   	|* advices is a lot of coding.
   	   	|* Can be done when customers request for it.
		return(get.utc(g.total.dldt))
	endif

	|**************************************
	|* Total line and ILC is not Implemented
	|**************************************
	if g.total.line and not g.ilc.implemented then
		return(get.utc(g.total.dldt))
	endif

	|**************************************
	|* It is not a total line
	|**************************************
	if g.create.expected.delivery.line.for.tdilc401 then
		|* For the expected sales order delivery line the
		|* actual delivery date is always zero
		return(utc(0,0))
	endif

	return(get.utc(tdsls045.ddat))
}
								|#143063.en


|function domain tcdate get.rate.date.field()		|#MCR.so
|{
|	|* the function returns the source date field and still needs to be
|	|* converted to UTC date.
|	if (tdsls040.fcrt = tcfcrt.ddta) and (tdsls041.ddta <> 0) then
|		return(tdsls041.ddta)
|	else
|		return(tdsls040.odat)
|	endif
|}							|#MCR.eo

function string get.release.date()
{
	if isspace(get.warehouse()) then
		return(utc(0,0))
	endif

|	return(utc(get.planned.delivery.date.field(), 0))	|#800-143063.o
	return(get.utc(get.planned.delivery.date.field()))	|#800-143063.n
}

								|#800-143063.so
|function string get.receipt.date()
|{
|	if tdsls041.prdt < tdsls041.ddta then
|		return(utc(get.planned.delivery.date.field(), 0))
||		return(utc(tdsls041.ddta, 0))
|	endif
|	return(utc(tdsls041.prdt, 0))
|}
								|#800-143063.eo
								|#800-143063.sn
function string get.receipt.date()
{
	if tdsls041.prdt < tdsls041.ddta then
		return(get.utc(get.planned.delivery.date.field()))
	endif
	return(get.utc(tdsls041.prdt))
}
								|#800-143063.en
								|#800-143063.sn
function string get.rate.date()
{
|	|* the function returns the source date field and still needs to be
|	|* converted to UTC date.
	if (tdsls040.fcrt = tcfcrt.ddta) and (tdsls041.ddta <> 0) then
		return(get.utc(tdsls041.ddta))
	endif
	return(get.utc(tdsls040.odat))
}
								|#800-143063.en
								|#800-143063.sn
function string get.invoice.date()
{
	return(get.utc(tdsls045.invd))
}
								|#800-143063.en
								|#800-143063.sn
function string get.utc(domain tcdate	i.date.field)
{
	if i.date.field = 0 then
		return(utc(0,0))
	else
		return(date.to.utc(i.date.field, TIME.MIN))
	endif
}
								|#800-143063.en



|*****************************************
|* Determine price/discounts fields
|*****************************************
function domain bcstr9 get.price.matrix.definition()
{
	static	domain	bcstr9	s.matrix.definition	fixed
	static	domain	tdplev	s.price.level

	if not double.cmp(tdsls045.oqua, 0.0, 0.0001) then
		|* If the oqua is zero no price matrix definition -> ""
		return("")
	endif

	if s.price.level <> tdsls041.plev then
		s.price.level = tdsls041.plev
		if get.price.matrix.definition.sls(
				tdsls041.plev,
				s.matrix.definition,
				g.error.message) = 0 then
		endif
	endif
	return(s.matrix.definition)
}

function domain bcstr9 get.disc.matrix.definition(
				long 	 	 i.element )
{
	static	domain	bcstr9	s.discount.matrix.definition	fixed
	static	domain	tddlev	s.discount.level

	if not double.cmp(tdsls045.pric, 0.0, 0.0001) then
		|* If the price is zero no discount matrix definition -> ""
		return("")
	endif

	if not double.cmp(tdsls045.disc(i.element), 0.0, 0.0001) and
	   not double.cmp(tdsls045.damt(i.element), 0.0, 0.0001) then




	   	|* No discount percentage/amount defined.
	   	return("")
	endif

	if s.discount.level <> tdsls041.dlev(i.element) then
		if get.discount.matrix.definition.sls(
				tdsls041.dlev(i.element),
				s.discount.matrix.definition,
				g.error.message) = 0 then
		endif
	endif
	return(s.discount.matrix.definition)
}

function long get.discount.matrix.type(
 	 	 	 long 	 	 i.element )
{
	if not double.cmp(tdsls045.pric, 0.0, 0.0001) then
		|* If the price is zero no discount matrix type -> none
		return(target(tdpcg.maty.none))
	endif

	if not double.cmp(tdsls045.disc(i.element), 0.0, 0.0001) and
	   not double.cmp(tdsls045.damt(i.element), 0.0, 0.0001) then
	   	|* No discount percentage/amount defined.
	   	return(target(tdpcg.maty.none))
	endif


 	 if tdsls041.dlev ( i.element ) = tddlev.contract or
 	 tdsls041.dlev ( i.element ) = tddlev.manual or
 	 tdsls041.dlev ( i.element ) = tddlev.not.def or
 	 tdsls041.disc ( i.element ) <> tdsls045.disc ( i.element ) or
 	 tdsls041.ldam ( i.element ) <> tdsls045.damt ( i.element ) then
 	 	 return ( target ( tdpcg.maty.none ))
 	 endif
 	 return ( target ( tdpcg.maty.soldsc ))
}

function long get.price.origin.sales(domain tdplev	i.price.level)
{
	if double.cmp(tdsls045.oqua, 0.0, 0.0001) = 0 then
		|* If ordered quantity is zero price origin not applicable
		return(target(tdgen.porg.not.applicable))
	endif

	on case i.price.level
	case tdplev.contract:
		return(target(tdgen.porg.contract))
	case tdplev.cust.item:
	case tdplev.plst.item:
		return(target(tdgen.porg.price.structure))
	case tdplev.ilst:
		return(target(tdgen.porg.def.pr.book))
	case tdplev.item:
		return(target(tdgen.porg.item.sls))
	case tdplev.not.def:
		return(target(tdgen.porg.not.applicable))
	default:
		break
	endcase

	return(target(tdgen.porg.manual))
}

function long get.discount.origin.sales(
		ref	domain	tddlev	i.discount.level(),
				long	i.element)
{
	if not double.cmp(tdsls045.pric, 0.0, 0.0001) then
		return(target(tdgen.dorg.not.applicable))
	endif

	if not double.cmp(tdsls045.disc(i.element), 0.0, 0.0001) and
	   not double.cmp(tdsls045.damt(i.element), 0.0, 0.0001) then
	   	|* No discount percentage/amount defined.
	   	return(target(tdgen.dorg.not.applicable))
	endif

	on case i.discount.level(i.element)
	case tddlev.contract:
		return(target(tdgen.dorg.contract))
	case tddlev.cust:
	case tddlev.cust.item:
	case tddlev.cust.pgrp:
	case tddlev.plst:
	case tddlev.plst.item:
	case tddlev.plst.pgrp:
	case tddlev.ilst:
		return(target(tdgen.dorg.disc.structure))
	case tddlev.not.def:
		return(target(tdgen.dorg.not.applicable))
	default:
		break
	endcase

	return(target(tdgen.dorg.manual))
}

function domain tccdsc get.discount.code(long	i.element)
{
	domain	tccdsc	l.discount.code

	if not double.cmp(tdsls045.pric, 0.0, 0.0001) then
		return("")
	endif

	if not double.cmp(tdsls045.disc(i.element), 0.0, 0.0001) and
	   not double.cmp(tdsls045.damt(i.element), 0.0, 0.0001) then
	   	|* No discount percentage/amount defined.
	   	return("")
	endif

	l.discount.code = tdsls041.cdis(1, i.element)
	return(l.discount.code)
}

function long get.discount.method(long	i.element)
{

	if not double.cmp(tdsls045.pric, 0.0, 0.0001) then
		return(target(tddmth.gross))
	endif

	if not double.cmp(tdsls045.disc(i.element), 0.0, 0.0001) and
	   not double.cmp(tdsls045.damt(i.element), 0.0, 0.0001) then
	   	|* No discount percentage/amount defined.
	   	return(target(tddmth.gross))
	endif

	return(etol(tdsls041.dmth(i.element)))
}

function long get.determining.flag()
{
			long		l.disc.lvl
			long		l.array.length

	l.array.length = tdsls.dll0022.array.length()
	for l.disc.lvl = 1 to l.array.length
		if tdsls041.dlev(l.disc.lvl) = tddlev.cust.pgrp then
			read.disc.parameters.by.customer.and.price.group(
								l.disc.lvl)
			return(etol(tdsls034.stsa))
		endif
		if tdsls041.dlev(l.disc.lvl) = tddlev.plst.pgrp then
			read.disc.parameters.by.price.list.and.price.group(
								l.disc.lvl)
			return(etol(tdsls035.stsa))
		endif
	endfor

	return(target(tcyesno.no))
}

function long get.eligible.flag()
{
			long		l.disc.lvl
			long		l.array.length

	l.array.length = tdsls.dll0022.array.length()
	for l.disc.lvl = 1 to l.array.length
		if tdsls041.dlev(l.disc.lvl) = tddlev.cust.pgrp then
			read.disc.parameters.by.customer.and.price.group(
								l.disc.lvl)
			return(etol(tdsls034.stsb))
		endif
		if tdsls041.dlev(l.disc.lvl) = tddlev.plst.pgrp then
			read.disc.parameters.by.price.list.and.price.group(
								l.disc.lvl)
			return(etol(tdsls035.stsb))

		endif
	endfor

	return(target(tcyesno.no))
}

function read.disc.parameters.by.customer.and.price.group(
			domain	tddile		i.discount.level)
{
	|* This function reads the discount parameter by customer price group


	static	domain	tcsuno		s.supplier



	static	domain	tcitem		s.item			fixed
	static	domain	tddile		s.discount.level

	if s.supplier = tdsls045.cuno and
	   s.item = tdsls041.item and
	   s.discount.level = i.discount.level then
		return
	else
		s.supplier = tdsls045.cuno
		s.item = tdsls041.item
		s.discount.level = i.discount.level
	endif

	get.item.inventory.unit.and.price.group()
	select	tdsls034.stsa, tdsls034.stsb
	from	tdsls034
	where	tdsls034._index1 = {	:tdsls045.cuno,
					:g.price.group,
					:i.discount.level}
	as set with 1 rows
	selectdo
	endselect
}

function read.disc.parameters.by.price.list.and.price.group(
			domain	tddile		i.discount.level)
{
	|* This function reads the discount parameter by
	|* price list and price group

		domain	tccplt		l.price.list
	static	domain	tcorno		s.order
	static	domain	tcitem		s.item			fixed
	static	domain	tddile		s.discount.level

	if s.order = tdsls045.orno and
	   s.item = tdsls041.item and
	   s.discount.level = i.discount.level then
		return
	else
		s.order = tdsls045.orno
		s.item = tdsls041.item
		s.discount.level = i.discount.level
	endif

	get.item.inventory.unit.and.price.group()
	l.price.list = get.price.list()
	select	tdsls035.stsa, tdsls035.stsb
	from	tdsls035
	where	tdsls035._index1 = {	:l.price.list,
					:g.price.group,
					:i.discount.level}
	as set with 1 rows
	selectdo
	endselect
}

function domain tccplt get.price.list()
{
	if not isspace(tdsls040.cpls) then
		return(tdsls040.cpls)
	endif

	if not isspace(tdsls040.pcpr) then
		read.customer(tdsls040.pcpr)
	else
		read.customer(tdsls040.cuno)
	endif

	return(tccom010.cpls)
}

function read.customer(
		domain	tccuno	i.get.customer)
{
	static	domain	tccuno		s.customer

	if s.customer = i.get.customer then
		return
	else
		s.customer = i.get.customer
	endif

	select	tccom010.cpls, tccom010.comp
	from	tccom010
	where	tccom010._index1 = {:i.get.customer}
	as set with 1 rows


	selectdo
	endselect
}

function long get.price.changes.allowed.after.delivery()
{
	if tdsls045.ddat <> 0 and
	   tdsls045.invn = 0 then
		return(target(tcyesno.yes))
	endif
	return(target(tcyesno.no))
}

function domain tcpric get.custom.value()
{
	|* Currently the custom value functionality is not yet fully implemented
	|* on SSA ERP ln 6.1
	|* Function will be used in a later version and for this version always
	|* 0.0 will be returned
	return(0.0)

|	if g.total.line then
|		return(0.0)
|	endif
|
|	if tdsls045.oqua > 0 then
|		return(tdsls041.pric)
|	else
|		return(0.0)
|	endif
}

function domain bcstd.fent get.contract.sales.office()
{
	static	domain	tcncmp		s.financial.company
	static	domain	bcstd.fent	s.contract.sales.office	fixed

	if tdsls045.cono = 0 then
		return("")
	endif

	read.customer(tdsls045.cuno)

	if s.financial.company = tccom010.comp then
		return(s.contract.sales.office)
	else
		s.financial.company = tccom010.comp
		s.contract.sales.office = ""
	endif

	if tccom010.comp <> 0 then
		g.ret = get.enterprise.unit(
			tccom010.comp,
			get.compnr(),
			g.error.message)
		s.contract.sales.office = bcstc018.sofd
	else
		s.contract.sales.office = bcstd000.sofc
	endif

	return(s.contract.sales.office)
}

function domain	bcorno	get.contract()
{
	static	domain	tcorno	s.old.contract
	static	domain	bcorno	s.new.contract	fixed

	if s.old.contract <> tdsls045.cono then
		s.old.contract = tdsls045.cono
		if tdsls045.cono <> 0 then
			s.new.contract = convert.number(
						bcckon.act.sls.contr,
						tdsls045.cono)
		else
			s.new.contract = ""
		endif
	endif
	return(s.new.contract)
}

function domain	tccvat get.tax()
{
	domain	tcccty	l.new.country	fixed
	domain	tccvat	l.new.tax	fixed

	get.tax.and.country(l.new.country, l.new.tax)
	return(l.new.tax)
}

function domain	tcccty get.tax.country()
{
	domain	tcccty	l.new.country	fixed
	domain	tccvat	l.new.tax	fixed

	get.tax.and.country(l.new.country, l.new.tax)
	return(l.new.country)
}

function get.tax.and.country(
		ref	domain	tcccty	o.new.country,
		ref	domain	tccvat	o.new.tax)
{

	static	domain tcccty	s.old.country	fixed
	static	domain tccvat	s.old.tax	fixed
	static	domain tcccty	s.new.country	fixed
	static	domain tccvat	s.new.tax	fixed

	if s.old.country = tdsls041.ccty and
	   s.old.tax = tdsls041.cvat then
		o.new.country = s.new.country
		o.new.tax = s.new.tax
		return
	else
		s.old.country = tdsls041.ccty
		s.old.tax = tdsls041.cvat
	endif

	g.ret = get.tax.by.country.code(
				tdsls041.ccty,
				tdsls041.cvat,
				s.new.country,
				s.new.tax,
				g.error.message)
	o.new.country = s.new.country
	o.new.tax = s.new.tax
}

|*****************************************
|* Determine logistic fields
|*****************************************
function domain tccwar	get.warehouse()
{
	if tdsls041.drct = tcyesno.yes then
		return("")
	else
		return(tdsls045.cwar)
	endif
}

function long get.inventory.handling()
{
	if tdsls041.isss = tcisss.issue.comp then
		return(target(tcinup.by.component))
	endif
	|* In all other cases issue by main item
	return(target(tcinup.by.main.item))
}

function long get.lot.selection()
{
	|* If lot control is lot by unit then lot is converted into a serial
	|* Serial will get lot code, serial selection is specific
	|* Lot is made empty and lot selection is any

	if isspace(get.warehouse()) then
		return(target(tclsel.any))
	endif

	if item.is.serialized() or
	   g.total.line then
		return(target(tclsel.any))
	endif
	return(etol(tdsls041.lsel))
}

function domain tdltc.clot get.lot()
{
	|* See comments for function get.lot.selection()
	if isspace(get.warehouse()) then
		return("")
	endif

	if item.is.serialized() or
	   g.total.line then
		return("")
	endif
	return(tdsls041.clot)
}

function long get.serial.selection()
{
	if isspace(get.warehouse()) then
		return(target(tdssel.any))
	endif

	if item.is.serialized() and
	   not g.total.line and
	   tdsls041.lsel = tclsel.specific then
		return(target(tdssel.specific))
	endif
	return(target(tdssel.any))
}

function domain tdltc.clot get.serial()
{
	|* See comments for function get.lot.selection()
	if g.total.line then
		return("")
	endif

	if isspace(get.warehouse()) then
		return("")
	endif

	if tdsls041.lsel = tclsel.any then
		return("")
	endif

	if item.is.serialized() then
		return(tdsls041.clot)
	endif
	return("")
}

function domain tcbool item.is.serialized()
{
	static	domain	tccprj	s.project		fixed
	static	domain	tcitem	s.item			fixed
	static	domain	tcbool	s.item.is.serialized

	if s.project <> tdsls045.cprj or
	   s.item <> tdsls045.item then
		s.item.is.serialized = serialized.item(
						tdsls045.cprj,
						tdsls045.item)
		s.project = tdsls045.cprj
		s.item = tdsls045.item
	endif
	return(s.item.is.serialized)
}

								|#SP1.sn
function domain tcbool item.is.lot.controlled()
{
	static	domain	tccprj	s.project		fixed
	static	domain	tcitem	s.item			fixed
	static	domain	tcbool	s.item.is.lot.controlled

	if s.project <> tdsls045.cprj or
	   s.item <> tdsls045.item then
		s.item.is.lot.controlled = lot.controlled.item(
						tdsls045.cprj,
						tdsls045.item)
		s.project = tdsls045.cprj
		s.item = tdsls045.item
	endif
	return(s.item.is.lot.controlled)
}
								|#SP1.en

								|#SP1.sn
function string get.lot.and.serial.set.401()
{
	domain	tcqsl1 		l.delivered.quantity
	domain	tcpono		l.sequence

	|* For the conversion of table 401 some additional checking needs to
	|* be done. This field is not filled for a total line or when the line
	|* is not yet delivered.

	|* Initialize
	g.lot.and.serial.set = ""

	if g.total.line then
		|* Lot and serial set not set on the total line
		return(g.lot.and.serial.set)
	endif

	l.delivered.quantity = get.delivered.quantity()
	if l.delivered.quantity = 0 then
		|* Order line is not delivered
		return(g.lot.and.serial.set)
	endif

	if item.is.lot.controlled() or
	   item.is.serialized() then
	   	if isspace(tdilc401.clot) and
	   	   isspace(tdsls041.clot) then
	   	   	|* If the item is lotcontrolled or serialized but no
	   	   	|* lot is not delivered then do not set the
	   	   	|* lot and serial set and consequently also not dump
	   	   	|* tcibd410 and ycibd411.
	   	   	|* This is migrating inconsistant data but because
	   	   	|* it is already delivered and WH also migrated we allow
	   	   	|* this migration anyway.
	   		return(g.lot.and.serial.set)
	   	endif
		l.sequence = get.order.line.sequence()
		g.lot.and.serial.set = edit$(tdsls045.orno, "999999") &
				       edit$(tdsls045.pono, "999") &
				       edit$(l.sequence, "999")
		return(g.lot.and.serial.set)
		|* This function detemines the guid for the lot and serial set
		|* The lot and serial set tables will be filled during
		|* dumping the tdsls406 records.
	endif
	return(g.lot.and.serial.set)
}
								|#SP1.en

function extern long get.shipping.constraint()
{
	if g.total.line or
	   tdsls041.drct = tcyesno.yes then
		|* For a total line or a direct delivery line the
		|* shipping constraint is not applicable and set to none.
		return(target(tdscon.none))
	endif

	if tdsls045.srnb > 0 then
		|* For backorders the shipping constraint is always none
		return(target(tdscon.none))
	endif

	if tdsls040.scom = tcyesno.yes then
		|* If the header is marked ship complete all lines are also
		|* marked as ship complete thus the shipping constraint is set
		|* to ship order complete.
		return(target(tdscon.oc))
	else
		if tdsls041.scom = tcyesno.yes then
		|* If the line is set to ship complete but the order is not set
		|* to ship complete then the shipping constraint will be set to
		|* ship line complete.
			return(target(tdscon.sc))
		else
		|* If the line and the header is not set to ship complete then
		|* the shipping constraint is set to None.
			return(target(tdscon.none))
		endif
	endif
}

function domain bcorno get.freight.order()
{
	static	domain	tcorno	s.transport.order
	static	domain	tcpono	s.transport.order.position
	static	domain	bcorno	s.freight.order

	if g.total.line then
		return("")
	endif

	if s.transport.order = tdsls045.torn and
	   s.transport.order.position = tdsls045.tpon then
			return(s.freight.order)
	endif

	s.transport.order = tdsls045.torn
	s.transport.order.position = tdsls045.tpon



	s.freight.order = ""
	if tdsls045.torn <> 0 then
		|* Check if freight order is converted
		if convert.transport.order.number(
					tdsls045.torn,
					tdsls045.tpon,
					g.error.message) <> 0 then
			|* transport order not converted
			s.freight.order = ""
		else
			s.freight.order = bcsfm001.norn
		endif
	endif
	return(s.freight.order)
}

function domain tcpono get.freight.order.position()
{
	domain	bcorno	l.freight.order

	l.freight.order = get.freight.order()
	if not isspace(l.freight.order) then
		|* If the transport order is converted to a freight order
		|* then for the transport order always freight order position
		|* 10 is created.
		return(10)
	endif
	return(0)
}

function long get.generate.freight.order()
{
	if generate.freight.order() = tcyesno.yes then
		return(target(tcyesno.yes))
	else
		return(target(tcyesno.no))
	endif
}

function domain tcyesno generate.freight.order()
{

	static	domain	tcorno		s.order
	static	domain	tcpono		s.position		|#800-141820.n
	static	domain	tcorno		s.torn
	static	domain	tcyesno		s.gen.freight.order
		domain	bcorno		l.freight.order
		domain	bcstc.lng2	l.dummy.acno

	if g.total.line then
		|* For total lines no freight orders
		return(tcyesno.no)
	endif

	if tdsls041.drct = tcyesno.yes then
		|* For direct delivery orders no freight orders
		return(tcyesno.no)
	endif

	if s.order = tdsls045.orno and
	   s.position = tdsls045.pono and			|#800-141820.n
	   s.torn = tdsls045.torn then
	   	return(s.gen.freight.order)
	else
		s.order = tdsls045.orno
		s.position = tdsls045.pono			|#800-141820.n
		s.torn = tdsls045.torn
		s.gen.freight.order = tcyesno.no
	endif

	|* Check if trtoc2200m000 is an activity of the order type
	|* If so then start with Generate freight order = yes else no

	if not activity.present.in.order.procedure("trtoc2200m000",
						    l.dummy.acno) then
		return(s.gen.freight.order)
	endif

	if tdsls045.torn = 0 then
								|#800-141820.sn
		if tdsls045.dqua <> 0 then
			|* If transport order is not yet generated and the
			|* the order line is already delivered then the
			|* freight order cannot be generated anymore on ERP LN.
			s.gen.freight.order = tcyesno.no
			return(s.gen.freight.order)
		endif

		if outbound.advice.present() then
			|* In BaanIV a transport order can be generated after
			|* deliveries are done. In ERP LN this is not possible.
			|* If an outbound advice is present then the sales
			|* order line cannot be changed anymore and thus the
			|* freight order cannot be generated anymore.
			|* If an advice is already present and the transport
			|* order is not created then the generate Freight order
			|* activity will be skipped for this order line.
			|* See also field documentation.
			s.gen.freight.order = tcyesno.no
			return(s.gen.freight.order)
		else
								|#800-141820.en
			|* Freight order can be generated
			s.gen.freight.order = tcyesno.yes
			return(s.gen.freight.order)
		endif
	endif

	|* transport order present
	l.freight.order = get.freight.order()
	if isspace(l.freight.order) then
		|* Freight order could not be converted
		s.gen.freight.order = tcyesno.no
	else
		s.gen.freight.order = tcyesno.yes
	endif
	return(s.gen.freight.order)
}

								|#800-141820.sn
function domain tcbool outbound.advice.present()
{
	if g.ilc.implemented then
		if g.no.of.outbound.advices.per.sls.sequence = 0 then
			|* Outbound advice for order line not present
			return(false)
		endif
	else
		|* No ILC situation no advices
		return(false)
	endif
	return(true)
}
								|#800-141820.en


function domain tcbool activity.present.in.order.procedure(
		domain	tcsess		i.activity,
	ref	domain	bcstc.lng2	o.tcmcs039.step.number)
{
	static	domain	tccotp		s.order.type
	static	domain	tcsess		s.activity
	static	domain	tcbool		s.order.step.present
		domain	tcbool		l.activity.defined
		domain	bcstc.lng2	l.order.step.number
		domain	bcstc.lng2	l.number.pmsk.positions
			long		l.actno

	if s.order.type = tdsls040.cotp and
	   s.activity = i.activity then
		return(s.order.step.present)
	else
		s.order.type = tdsls040.cotp
		s.activity = i.activity
		s.order.step.present = false
	endif

	l.activity.defined = false
	for l.actno = 1 to 20
		if strip$(g.old.session.code.activities.array(1,l.actno)) =
							strip$(i.activity) then
			|* activity defined in tcmcs039
			l.order.step.number = l.actno
			l.activity.defined = true
			break
		endif
	endfor

	if l.activity.defined then
		l.number.pmsk.positions = fill.max.stepno.isls0014()
		for l.actno = 1 to l.number.pmsk.positions
			|* Check if activity is present in the order type.
			if tcmcs042.stno(l.actno) = 0 then
				|* No more activities defined for the
				|* order type -> stop checking order
				|* type.
				break
			endif
			if l.order.step.number = tcmcs042.stno(l.actno) then
				|* Activity present in order
				|* procedure.
				s.order.step.present = true
				break
			endif
		endfor
	endif

	o.tcmcs039.step.number = l.order.step.number
	return(s.order.step.present)
}

function long get.freight.invoice()
{
|* Expl	:
|* This function is called when records in table trtrc140-maintain rate codes
|* by customer, are present. If records exists in this table then for each
|* order this table needs to be checked if for the sales customer a record
|* exists. If for the customer a rate code by customer exists then field the
|* tdsls401.frin is mapped with "yes" if all other cases the field will have the
|* default value.
|* For cost and return orders the default value is used.

	if generate.freight.order() = tcyesno.yes and
	   tcmcs042.reto = tcyesno.no and
	   tcmcs042.sund = tcyesno.no then
		select	trtrc140.cuno
		from	trtrc140
		where	trtrc140.cuno = :tdsls040.cuno
		as set with 1 rows
		selectdo
			return(target(tcyesno.yes))
		endselect
	endif
	return(target(tcyesno.no))
}

function string get.freight.service.level()
{
	static	domain	tccprj		s.project		fixed
	static	domain	tcitem		s.item			fixed
	static	domain	trtco.serv	s.service.level		fixed

	if generate.freight.order() = tcyesno.no then
		|* No freight order will be or is generated ->
		|* no freight service level required.
		return("")
	endif

	if tdsls045.cprj = s.project and
	   tdsls045.item = s.item then
		return(s.service.level)
	else
		s.project = tdsls045.cprj
		s.item = tdsls045.item
		s.service.level = ""
	endif

	select	trtcd120.serv:s.service.level
	from	trtcd120
	where	trtcd120._index1 = {	:tdsls045.cprj,
					:tdsls045.item}
	as set with 1 rows
	selectdo
	endselect
	return(s.service.level)
}

								|#800-143063.so
|function domain	bcorno	get.shipment()
|{
|	domain	bcorno	l.shipment	fixed
|
|	|* WH requires to convert delivered sales orders to shipments.
|	|* SLS requires to have a link between a shipment and a delivered sales
|	|* order.
|	|* To make sure that WH and SLS will use the same shipment id's and
|	|* shipment lines the following rules apply:
|	|* - As Shipment ID on the target a combination between sales order and
|	|*   sales position (from the source side) will be used.
|	|* - As Shipment line on the target the sequence number of the delivery
|	|*   line on the source side will be used.
|
|	l.shipment = ""
|
|	if g.total.line then
|		return(l.shipment)
|	endif
|
|	if tdsls045.ddat <> 0 and
|	   not isspace(tdsls045.cwar) then
|		l.shipment = edit$(tdsls045.orno, "999999") &
|			     edit$(tdsls045.pono, "999")
|	endif
|	return(l.shipment)
|}
								|#800-143063.eo
								|#800-143063.sn
function domain	bcorno	get.shipment()
{
	|* WH requires to convert delivered sales orders to shipments.
	|* SLS requires to have a link between a shipment and a delivered sales
	|* order.
	|* To make sure that WH and SLS will use the same shipment id's and
	|* shipment lines the following rules apply:
	|* - As Shipment ID on the target a combination between sales order and
	|*   sales position (from the source side) will be used.
	|* FOR SHIPMENT LINE SEE FUNCTION GET.SHIPMENT.LINE

	domain	bcorno	l.shipment	fixed

	l.shipment = ""

	if g.total.line then
		return(l.shipment)
	endif

	if g.ilc.implemented then
		if g.create.expected.delivery.line.for.tdilc401 then
			|* No delivery done for expected advice thus no shipment
			l.shipment = ""
		else
			|* Outbound advice delivered
			if tdsls045.ddat <> 0 and
		   	   not isspace(tdsls045.cwar) then
				l.shipment = edit$(tdsls045.orno, "999999") &
					     edit$(tdsls045.pono, "999")
			endif
		endif
	else
		if tdsls045.ddat <> 0 and
		   not isspace(tdsls045.cwar) then
			l.shipment = edit$(tdsls045.orno, "999999") &
				     edit$(tdsls045.pono, "999")
		endif
	endif
	return(l.shipment)
}
								|#800-143063.en

								|#800-143063.so
|function domain	tcsrnb get.shipment.line()
|{
|	domain	tcsrnb	l.shipment.line
|
|
|	if g.total.line then
|		return(0)
|	endif
|
|	if tdsls045.ddat <> 0 and
|	   not isspace(tdsls045.cwar) then
|		return(tdsls045.srnb)
|	endif
|	return(0)
|}
								|#800-143063.eo
|								|#202924.so
|								|#800-143063.sn
|function domain	tcpono get.shipment.line()
|{
|	|**********************************************************************
|	|* WH requires to convert delivered sales orders to shipments.
|	|* SLS requires to have a link between a shipment and a delivered sales
|	|* order.
|	|* To make sure that WH and SLS will use the same shipment id's and
|	|* shipment lines the following rules apply:
|	|* - As Shipment ID on the target a combination between sales order and
|	|*   sales position (from the source side) will be used.
|	|* - As Shipment line on the target the following rules are applied:
|	|*   ILC: As Shipment line the record no. of the delivered tdilc401 is
|	|* 	  used as shipment line number
|	|*   NON ILC: For each new shipment the Shipment line will start at 1
|	|*	      When for the same order/ posistion combination another
|	|*	      sales delivery is done this will result in a new shipment
|	|*	      line for the same shipment
|	|*	      stepsize in the shipment is 1 this stepsize is also used
|	|*	      when migrating shipments lines (Wh).
|	|**********************************************************************
|	|* Migrating shipments and migrating sales orders must loop indentical
|	|* through the source sales orders and the source outbound advices.
|	|* This will result in same sales sequences / shipment lines.
|	|* In case of mismatches the solution must be found in the way the
|	|* migration object loops through the source objects.
|	|**********************************************************************
|
|	static	domain	tcpono	s.shipment.line
|	static	domain	tcorno	s.order
|	static	domain	tcpono	s.position
|
|	if g.total.line then
|		return(0)
|	endif
|
|	if g.ilc.implemented then
|		s.shipment.line = 0	|* initialize shipment line
|		if g.create.expected.delivery.line.for.tdilc401 then
|			|* No delivery done for expected advice thus no shipment
|			return(0)
|		else
|			if tdsls045.ddat <> 0 and
|		   	   not isspace(tdsls045.cwar) then
|		   	   |* Outbound advice delivered -> shipment line is set
|			   |* Equal to the processed tdilc401 record.
|				s.shipment.line = g.outbound.advice.record
|			else
|				return(0)
|			endif
|		endif
|	else
|		if tdsls045.ddat <> 0 and
|		   not isspace(tdsls045.cwar) then
|			|* Sales order line sequence = delivered thus shipment
|			|* line must be determined. Check if the shipment line
|			|* is required for the same shipment or a new one.
|			|* Same shipment the shipment line is previous shipment
|			|* line + 1. (stepsize = 1)
|			|* New shipment shipment line start with 1.
|			if s.order <> tdsls045.orno or
|			   s.position <> tdsls045.pono then
|				s.order = tdsls045.orno
|				s.position = tdsls045.pono
|				s.shipment.line = 0
|				|* initialize shipment line for new shipment
|			endif
|
|			s.shipment.line = s.shipment.line + 1
|		else
|			|* No delivery done thus no shipment
|			return(0)
|		endif
|	endif
|
|	return(s.shipment.line)
|
|}
|							|#800-143063.en
|							|#202924.eo
							|#202924.sn
function domain	tcpono get.shipment.line()
{
	|**********************************************************************
	|* WH requires to convert delivered sales orders to shipments.
	|* SLS requires to have a link between a shipment and a delivered sales
	|* order.
	|* To make sure that WH and SLS will use the same shipment id's and
	|* shipment lines the following rules apply:
	|* - As Shipment ID on the target a combination between sales order and
	|*   sales position (from the source side) will be used.
	|* - As Shipment line on the target the migrated sales order sequence
	|*   number is used.
	|*   For each sales order line sequence number (delivery) one shipment
	|*   line exists.
	|*   The migrated sales order line sequence nr is taken because this is
	|*   the data that is available at tdsls401, whinh431 and whinr110
	|* Note:
	|* There is one exeption: When the migrated sales order line sequence
	|* is equal to zero then the shipment line will be set to 10.
	|**********************************************************************

	domain	tcpono	l.sales.sequence
	domain	tcpono	l.shipment.line

	if g.total.line then
		|* No shipment / shipment line on a total line
		return(0)
	endif

	if g.ilc.implemented then
		if g.create.expected.delivery.line.for.tdilc401 then
			|* No delivery done for expected advice thus no shipment
			return(0)
		endif
	endif

	if tdsls045.ddat <> 0 and
	   not isspace(tdsls045.cwar) then
		|* shipment line is set equal to the migrated sales sequence.
		l.sales.sequence = get.order.line.sequence()
		if l.sales.sequence = 0 then
			l.shipment.line = 10
		else
			l.shipment.line = l.sales.sequence
		endif
		return(l.shipment.line)
	endif

	|* no shipment done
	return(0)
}
								|#202924.en

|*****************************************
|* Determine quantity fields
|*****************************************
function domain tcqsl1 quantity.from.order.unit.to.inventory.unit (
 	 	 domain 	 tcqrd1  	 i.quantity.in.order.unit )
{
	get.item.inventory.unit.and.price.group()
 	 return ( itccom0007.qty.domain.round (
 	 	 	 i.quantity.in.order.unit * tdsls041.cvqs,
 	 	 	 "tcqsl1",
 	 	 	 g.inventory.unit))
}


								|#143063.so
|function domain tcqsl1 get.ordered.quantity()
|{
|	if g.total.line then
|		return(g.total.qoor)
|	else
|		return(tdsls045.oqua)
|	endif
|}
								|#143063.eo
								|#143063.sn
function domain tcqsl1 get.ordered.quantity()
{
	|******************************************************************
	|* Get ordered qty for a total line
	|******************************************************************
	if g.total.line then
		return(g.total.qoor)
	endif

	|******************************************************************
	|* Get Ordered qty when ILC implemented and multiple advices present
	|******************************************************************
	if g.ilc.implemented and
	   g.no.of.outbound.advices.per.sls.sequence > 1 then
		if g.create.expected.delivery.line.for.tdilc401 then
			|* Create expected delivery line for outbound advice
			|* Expected delivery is the ordered qty minus the
			|* already delivered quantity. Values can be taken from
			|* the sales order line
			return(tdsls045.oqua - tdsls045.dqua)
		endif

		if g.outbound.advice.record =
				g.no.of.outbound.advices.per.sls.sequence then
			|* If all advices present are delivered but a backorder
			|* quantity is still defined then for the last
			|* advice the ordered qty will be the delivered
			|* adviced quantity + Backrder quantity
			return(tdilc401.qsts + tdsls045.bqua)
		else
			|* Create a sales order delivery line for the delivered
			|* outbound advice record. ordered quantity is equal to
			|* the delivered quantity.
			|* The qsts field is the quantity in inventor unit.
			return(tdilc401.qsts)
		endif
	endif

	|******************************************************************
	|* Get ordered qty for Non-ILC situation and ILC situation but only
	|* 1 advice present for the sales order line sequence.
	|******************************************************************
	return(tdsls045.oqua)

}
								|#143063.en

								|#143063.so
|function domain tcqsl1 get.delivered.quantity()
|{
|	domain	tcqsl1 l.converted.delivered.quantity
|
|	l.converted.delivered.quantity = 0.0
|	if g.total.line then
|		l.converted.delivered.quantity =
|			quantity.from.order.unit.to.inventory.unit(
|								g.total.qidl)
|	else
|		l.converted.delivered.quantity =
|			quantity.from.order.unit.to.inventory.unit(
|								tdsls045.dqua)
|	endif
|	return(l.converted.delivered.quantity)
|}
								|#143063.eo
								|#143063.sn
function domain tcqsl1 get.delivered.quantity()
{
	domain	tcqsl1 l.converted.delivered.quantity

	l.converted.delivered.quantity = 0.0

	|******************************************************************
	|* Get delivered qty for the total line
	|******************************************************************
	if g.total.line then
		l.converted.delivered.quantity =
			quantity.from.order.unit.to.inventory.unit(
								g.total.qidl)
		return(l.converted.delivered.quantity)
	endif

	|******************************************************************
	|* Get delivered qty in ILC situation and for this orderline sequence
	|* there are more than one advice (delivered or not delivered)
	|* If one advice is present than the values from the sales order line
	|* can be used (next section).
	|* For a delivered advice 	-> Delivered qty = advice qty
	|* For a not delivered advice 	-> Delivered qty = 0
	|******************************************************************
	if g.ilc.implemented and
	   g.no.of.outbound.advices.per.sls.sequence > 1 then
	   	if g.create.expected.delivery.line.for.tdilc401 then
			|* For the expected sales order delivery line the
			|* delivered quantity is always zero
			l.converted.delivered.quantity = 0.0
		else
			|* For the delivered outbound advice the delivered
			|* quantity of the sales order delivery line is equal
			|* to the advised quantity of the tdilc401 record.
			|* The qsts field is the quantity in inventor unit.
			l.converted.delivered.quantity = tdilc401.qsts
		endif
		return(l.converted.delivered.quantity)
	endif

	|******************************************************************
	|* In all other cases
	|******************************************************************
	l.converted.delivered.quantity =
				quantity.from.order.unit.to.inventory.unit(
								tdsls045.dqua)

	return(l.converted.delivered.quantity)
}
								|#143063.en

								|#143063.so
|function domain tcqsl1 get.backorder.quantity()
|{
|	if g.total.line then
|		return(g.total.qbbo)
|	else
|		return(tdsls045.bqua)
|	endif
|}
								|#143063.eo
								|#143063.sn
function domain tcqsl1 get.backorder.quantity()
{
	|******************************************************************
	|* Get backorder qty for the total line
	|******************************************************************
	if g.total.line then
		|**********************
		|* ILC Situation
		|**********************
		if g.create.expected.delivery.line.for.tdilc401 then
		|* If an expected sales order delivery line is created
		|* then the backorder qty is handled by the expected delivery
		|* line created.
			return(0.0)
		endif
		|**********************
		|* All other cases for a total line
		|**********************
		return(g.total.qbbo)
	endif

	|******************************************************************
	|* Get backorder quantity in the ILC situation and multiple advices
	|* present for the sales order line sequence.
	|* Backorder qty will be set for delivery line created for the last
	|* advice for the sales order line sequence.
	|* When not yet delivered advice are present then an expected delivery
	|* line will be created. The backorder qty is then handled by the
	|* expected delivery line.
	|* If all advices present are delivered then the backorder qty is
	|* set for the last to be created delivery line.
	|******************************************************************
	if g.ilc.implemented and
	   g.no.of.outbound.advices.per.sls.sequence > 1 then
		if g.outbound.advice.record <
				g.no.of.outbound.advices.per.sls.sequence then
			|* Backorder quantity is handled by the delivery line
			|* for the last advice or on the expected sales order
			|* delivery line.
			return(0.0)
		endif
		if g.create.expected.delivery.line.for.tdilc401 then
			|* Backorder quantity is on the target handled by the
			|* ordered qty of the expected sales order deliveryline.
			|* Backorder qty set to zero.
			return(0.0)
		endif
		if g.outbound.advice.record =
				g.no.of.outbound.advices.per.sls.sequence then
			|* Last advice
			return(tdsls045.bqua)
		endif
	endif

	|******************************************************************
	|* Get backorder qty in a NON-ILC situation.
	|******************************************************************
	return(tdsls045.bqua)
}
								|#143063.en

function domain tcqsl1 get.committed.quantity()
{
	domain	tcqsl1 l.converted.committed.quantity

	l.converted.committed.quantity = 0.0
	if not g.total.line and
	   tdsls045.ddat = 0 then
		|* when sales order line is already delivered
		|* committed quantity on the target is 0
		l.converted.committed.quantity =
			quantity.from.order.unit.to.inventory.unit(
								tdsls045.recq)
	endif
	return(l.converted.committed.quantity)
}

|								|#202399.so
|function long get.backorder.confirmed.flag()
|{
||*	if the backorder quantity is filled and a record with a higher
||* 	sequence number exists then the backorder is confirmed.
||*	The confirmed flag is not applicable for total lines.
|
||#800-143070.so
||	if backorder.confirmed() then
||#800-143070.eo
||#800-143070.sn
|	if not g.total.line and
|	   backorder.confirmed() then
||#800-143070.en
|		return(1)
|	endif
|
|	return(2)
|}
|
|function domain	tcbool	backorder.confirmed()
|{
||#800-143070.so
||	if not g.total.line and
||	   double.cmp(tdsls045.bqua, 0.0, 0.0001) <> 0 and
||#800-143070.eo
||#800-143070.sn
|	   if double.cmp(tdsls045.bqua, 0.0, 0.0001) <> 0 and
||#800-143070.en
|	   tdsls045.srnb < get.no.of.delivery.lines() then
|		return(true)
|	endif
|	return(false)
|}
|								|#202399.eo
								|#202399.sn
function long get.backorder.confirmed.flag()
{
|*	if the backorder quantity is filled and a record with a higher
|* 	sequence number exists then the backorder is confirmed.
|*	The confirmed flag is not applicable for total lines.
	if not g.total.line and
	   backorder.confirmed(tdsls045.bqua, tdsls045.srnb) then
		return(1)
	endif

	return(2)
}

function domain	tcbool	backorder.confirmed(
			domain	tcqsl1	i.backorder.quantity,
			domain	tcpono	i.sales.sequence)
{
	if double.cmp(i.backorder.quantity, 0.0, 0.0001) <> 0 and
	   i.sales.sequence < get.no.of.delivery.lines() then
		return(true)
	endif
	return(false)
}
								|#202399.en


function domain tcsrnb get.linked.sequence.order.line()
{
|*	The linked order line sequence points to the sequence number from which
|*	this line is created -> thus points always to the previous delivery line
|* 	in the source version.
|*	linked sequence in source version =
|*				converted sequence number in target + 1
|*	converted sequence number in target = current sequence number + 1
|*	Thus the linked order line sequence in the target is mapped with the
|*	sequence number + 2 on the source side.
|*	The linked sequence is not applicable for total lines.

	if not g.total.line and
	   tdsls045.srnb < get.no.of.delivery.lines() then
		return(tdsls045.srnb + 2)
	endif
	return(0)
}

function get.item.inventory.unit.and.price.group()
{
	static	domain	tcorno	s.order
	static	domain	tcpono	s.position

	if s.order = tdsls045.orno and
	   s.position = tdsls045.pono then
	   	return
	else
		s.order = tdsls045.orno
		s.position = tdsls045.pono
		g.inventory.unit = ""
	endif

	if not isspace(tdsls045.cprj) and
	   tdsls041.opol = tcittc.customized then
		select	tipcs021.cuni:g.inventory.unit,
			tiitm001.cpgs:g.price.group
		from	tipcs021, tiitm001
		where	tipcs021._index1 = {:tdsls045.cprj, :tdsls045.item}
		and	tipcs021.dfit refers to tiitm001 unref clear
		as set with 1 rows
		selectdo
		endselect
		if isspace(g.price.group) then
			g.price.group = bcstd000.cprg
		endif
	else
		select	tiitm001.cuni:g.inventory.unit,
			tiitm001.cpgs:g.price.group
		from	tiitm001
		where	tiitm001._index1 = {:tdsls045.item}
		as set with 1 rows
		selectdo
		endselect
	endif
}

|***************************
|*  Retrieve amount related fields
|***************************
function domain tcamnt get.order.discount.amount()
{
	if g.total.line then

		return(g.total.amod)
	else
		return(tdsls045.odam)
	endif
}

function domain tcamnt get.order.line.discount.amount()
{
	if g.total.line then
		return(g.total.amld)
	else
		return(tdsls045.ldam)
	endif
}

function domain tcamnt get.delivered.amount()
{
	if g.total.line then
		return(g.total.damt)
	endif

	if tdsls045.ddat <> 0 then
		return(tdsls045.amnt)
	else
		return(0.0)
	endif
}

function domain tcamnt get.order.line.amount()
{
	domain	tcamnt	l.dummy.line.disc.amount
	domain	tcamnt	l.order.line.amount

	if g.total.line then
		return(g.total.oamt)
	endif

	if tdsls045.ddat = 0 then
		return(tdsls045.amnt)
	endif

	if double.cmp(tdsls045.oqua, 0.0, 0.0001) and
	   double.cmp(tdsls045.pric, 0.0, 0.0001) then
		|* Records where oqua, pric and oamt are zero are not selected.
		|* if oqua and pric are zero then oamt must be filled.
		|* recalculation based upon oqua and pric will lead to zero so
		|* in this case no recalculation.
		return(tdsls045.amnt)
	endif

	|* determine oamt based upon oqua
 	 tdsls.dll0022.calc.net.amount (
	 	 tdsls041.cvqs,
	 	 tdsls041.cvps,
	 	 tdsls045.oqua,
	 	 tdsls045.pric,
	 	 tdsls040.ccur,
 		 tcmcs002.crnd,
	 	 tdsls041.dmth,
	 	 tdsls045.disc,
 		 tdsls045.damt,
	 	 l.order.line.amount, 		| * ref
	 	 l.dummy.line.disc.amount ) 	| * ref
	return(l.order.line.amount)
}

|*****************************************
|*  Retrieve activity related fields
|*****************************************
function domain bcstd.acti get.current.activity()
{
	domain	tcpmsk		l.procedure.mask
	domain	bcstd.acti	l.current.activity	fixed
		long		l.step.number

	l.current.activity = ""
	if not g.total.line then
		l.procedure.mask = get.procedure.mask()
		l.step.number = pos(l.procedure.mask, "y")
		if l.step.number <> 0 then
		      l.current.activity = get.new.session.code.for.step.number(
						tdsls040.cotp,
						l.step.number)
		else
			|* When all activities are executed including
			|* Process delivered sales orders then the activity is
			|* set to delete sales order
			l.current.activity = "tdsls4224m000"
		endif
	endif
	return(l.current.activity)
}

function domain tcpmsk get.procedure.mask()
{
		domain	bcstc.lng2	i
		domain	bcstc.lng2	l.new.pmsk.position
		domain	bcstc.lng2	l.number.pmsk.positions
		domain	tcsess		l.old.activity
		domain	tcsess		l.new.activity
	static	domain	tcpmsk		s.procedure.mask	fixed
	static	domain	tcbool		s.total.line
	static	domain	tcorno		s.orno
	static	domain	tcpono		s.pono
	static	domain	tcsrnb		s.srnb

	if s.orno = tdsls045.orno and
	   s.pono = tdsls045.pono and
	   s.srnb = tdsls045.srnb and
	   s.total.line = g.total.line then
		return(s.procedure.mask)
	else
		s.orno = tdsls045.orno
		s.pono = tdsls045.pono
		s.srnb = tdsls045.srnb
		s.total.line = g.total.line
		s.procedure.mask = "nnnnnnnnnnnnnnnnnnnn"
	endif

	if g.total.line then
		s.procedure.mask = "nnnnnnnnnnnnnnnnnnne"
		return(s.procedure.mask)
	endif

	l.number.pmsk.positions = fill.max.stepno.isls0014()
	for i = 1 to l.number.pmsk.positions
		if tdsls045.pmsk(i;1) = "n" then
			continue
		endif

		|* Get session code for procedure mask position
		l.old.activity = g.old.session.code.activities.array(1,i)

		|* convert old source session codes to new target session codes
		l.new.activity = convert.old.activity(l.old.activity)

		|* Retrieve new procedure mask position for target activity
		l.new.pmsk.position = get.new.pmsk.position(
							tdsls040.cotp,
							l.new.activity)



		if l.new.pmsk.position <> 0 then
			s.procedure.mask(l.new.pmsk.position;1) =
							tdsls045.pmsk(i;1)
		endif
	endfor

	for i = 1 to l.number.pmsk.positions
		|* Fill pmsk with "y" with the new target activities
		l.new.activity = ""
		if s.procedure.mask(i;1) <> "n" then
			continue
		endif
		l.new.activity = get.new.session.code.for.step.number(
					tdsls040.cotp,
					i)
		if not isspace(l.new.activity) then
			 s.procedure.mask(i;1) = "y"
		endif
	endfor

	s.procedure.mask = check.and.correct.pmsk(s.procedure.mask)


	return(s.procedure.mask)
}

function fill.old.session.code.activities.array()
{
		domain	tcsess		l.old.session.code.activity
			long		i

	for i = 1 to 20
		select	tcmcs039.sess:l.old.session.code.activity
		from	tcmcs039
		where	tcmcs039._index2 = {	tcmodc.sls,
						:i}
		as set with 1 rows
		selectdo
		selectempty
			l.old.session.code.activity = ""
		endselect

		g.old.session.code.activities.array(1,i) =
					l.old.session.code.activity
	endfor
}


function domain	tcsess	convert.old.activity(
				domain	tcsess i.old.activity.code)
{
	domain	tcsess	l.new.activity.code

|********************************************************************
|*	OLD Session	-> NEW Session
|*	"tdsls4223m000" -> no change		(PROCESS.LINE.SLS)
|*	"tdsls4401m000"	-> No change		(PRNT.ORD.ACK)
|*	"tdinv2201m000" -> "whinp2200m000"	(GEN.ORD.COMM)
|*	"tipcs2240m000"	-> "tdsls4244m000" 	(GEN.OB.STRUC)
|*	"trtoc2200m000"	-> "tdsls4222m000"	(GEN.FRT.ORDR)
|*
|*			-> "tdsls4224m000"	(DELETE.LINE.SLS)
|*			-> "tdsls4240m000"	(GEN.PUR.ADVI)
|*			-> "tdsls4246m000"	(RLSE.TO.WRHS)
|*			-> "tdsls4247m000"	(RLSE.TO.INVO)
|*			-> "tdsls4101m200"	(MAINT.DELIVERIES)
|********************************************************************
	on case strip$(i.old.activity.code)
	case "tdinv2201m000":
		l.new.activity.code = "whinp2200m000"
		break
	case "tipcs2240m000":
		l.new.activity.code = "tdsls4244m000"
		break
	case "trtoc2200m000":
		l.new.activity.code = "tdsls4222m000"
		break

	default:
		l.new.activity.code = i.old.activity.code
	endcase
	return(l.new.activity.code)
}

|function domain	bcstc.lng2	get.new.pmsk.position(
|			domain	tccotp	i.order.type,
|			domain	tcsess	i.new.activity)
|{
|	|* This function returns the new activity number
|	|* for the activity.
|	|* If the activity is not part of the order type
|	|* the new activity number is 0
|
|	domain	bcstc.lng2	l.new.activity.number
|
|	l.new.activity.number = 0
|
|	select	bcstd001.acno:l.new.activity.number
|	from	bcstd001
|	where	bcstd001._index1 = {	:i.order.type,
|					:i.new.activity}
|	as set with 1 rows
|	selectdo
|	endselect
|	return(l.new.activity.number)
|}
function domain	bcstc.lng2	get.new.pmsk.position(
			domain	tccotp	i.order.type,
			domain	tcsess	i.new.activity)
{
	|* This function returns the new activity number
	|* for the activity.
	|* If the activity is not part of the order type
	|* the new activity number is 0

	domain	bcstc.lng2	l.new.activity.number
	domain	bcstc.lng2	i
	domain	tcsess		l.new.session.codes.by.step.number(20)	fixed

	load.new.session.codes.new.order.type.into.array(
				i.order.type,
				l.new.session.codes.by.step.number)

	l.new.activity.number = 0

	for i = 1 to 20
		if l.new.session.codes.by.step.number(1,i) =
						strip$(i.new.activity) then
			l.new.activity.number = i
			break
		endif
	endfor
	return(l.new.activity.number)
}

|function domain tcsess get.new.session.code.for.step.number(
|		domain	tccotp		i.order.type,
|		domain	bcstc.lng2	i.current.step.number)
|{
|	|* This function returns the new activity code
|	|* for a new target activity.
|	|* The pmsk must also be set for this new activity
|
|	domain	tcsess	l.new.activity.code
|
|	l.new.activity.code = ""
|
|	select	bcstd001.acti:l.new.activity.code
|	from	bcstd001
|	where	bcstd001._index2 = {	:i.order.type,
|					:i.current.step.number}
|	as set with 1 rows
|	selectdo
|	endselect
|	return(l.new.activity.code)
|}

function domain tcsess get.new.session.code.for.step.number(
		domain	tccotp		i.order.type,
		domain	bcstc.lng2	i.current.step.number)
{
	|* This function returns the new activity code
	|* for a new target activity.
	|* The pmsk must also be set for this new activity

	domain	tcsess	l.new.session.codes.by.step.number(20)	fixed

	load.new.session.codes.new.order.type.into.array(
				i.order.type,
				l.new.session.codes.by.step.number)

	return(l.new.session.codes.by.step.number(1, i.current.step.number))
}

function load.new.session.codes.new.order.type.into.array(
			domain	tccotp	i.order.type,
		ref	domain	tcsess	o.new.session.codes.for.order.type())
{
	static	domain	tccotp	s.order.type				fixed
	static	domain	tcsess	s.new.session.codes.for.order.type(20)	fixed
			long	i

	if s.order.type <> i.order.type then
		s.order.type = i.order.type
		|* reset array before loading.
		for i = 1 to 20
			s.new.session.codes.for.order.type(1, i) = ""
		endfor
		|* Load new order type session into array
		select	bcstd001.cotp, bcstd001.acti, bcstd001.acno
		from	bcstd001
		where	bcstd001._index2 = {	:i.order.type }
		selectdo
			s.new.session.codes.for.order.type(1, bcstd001.acno) = bcstd001.acti
		endselect
	endif
	o.new.session.codes.for.order.type = s.new.session.codes.for.order.type
	return
}

function domain	tcpmsk	check.and.correct.pmsk(
			domain	tcpmsk	i.procedure.mask)
{
	domain	bcstc.lng2	l.position
	domain	bcstc.lng2	l.number.pmsk.positions
	domain	tcsess		l.not.executed.acti
	domain	bcorno		l.freight.order
	domain	tcpmsk		l.procedure.mask

	l.procedure.mask = i.procedure.mask

	l.number.pmsk.positions = fill.max.stepno.isls0014()
	for l.position = 1 to l.number.pmsk.positions
		if l.procedure.mask(l.position;1) <> "y" then
			continue
		endif

		l.not.executed.acti = get.new.session.code.for.step.number(
						tdsls040.cotp,
						l.position)

		on case strip$(l.not.executed.acti)
|#SL201971.sn
		case "tdsls4401m000":
		     |* Print order acnowledgement
			if tdsls045.srnb > 0 then
				|* for backorder this activity is not valid
				|* Already printed on existing order.
				l.procedure.mask(l.position;1) = "n"
			endif
			break
		case "tdsls4244m000":
		     |* Generate (project) structure
			if tdsls045.srnb > 0 then
				|* for backorder this activity is not valid
				|* Structure already generated on existing order.
				l.procedure.mask(l.position;1) = "n"
			endif
			break
|#SL201971.en

		case "tdsls4222m000":
		     |* Generate Freight orders
			if tdsls045.torn <> 0 then
				|* if transport order is present on the source
				|* but cannot be converted then the freight
				|* order on the target will be made empty and
				|* the activity is not applicable
				l.freight.order = get.freight.order()
				if isspace(l.freight.order) then
					l.procedure.mask(l.position;1) = "n"
				endif
			endif
			break
		case "tdsls4240m000":
		     |* Generate Purchase order advice
			|* if purchase order advice is present or the purchase
			|* order is already present then set to "e" .
			|* If not then generate PO advice is the next step if it
			|* is a direct delivery order line.
			|* If the PO advice is not present and it is not a
			|* direct delivery then the PO advice step will be set
			|* to No.
			if purchase.advice.present() or
			   tdsls041.porn <> 0 then
				l.procedure.mask(l.position;1) = "e"
			else
				if tdsls041.drct = tcyesno.no then
					l.procedure.mask(l.position;1) = "n"
				endif
|#800-143070.sn
				if tdsls045.srnb > 0 then
				|* for backorder this activity is not valid
					l.procedure.mask(l.position;1) = "n"
				endif
|#800-143070.en
			endif
			break
		case "tdsls4246m000":
		     |* Release to Warehousing
			if not isspace(tdsls045.cwar) then
				|* Warehouse filled -> rel to wh applicable
				|* If the warehouse on the sales order on the
				|* source is filled then on the target the
				|* Release to Warehousing activity must be set.
				if set.release.to.warehousing.to.executed() then
					|* default value "y" canged to "e"
					l.procedure.mask(l.position;1) = "e"
				endif
			else
				|* default value "y" canged to "n"
				l.procedure.mask(l.position;1) = "n"
			endif
			break
		case "tdsls4101m200":
		     |* Maintain deliveries for sales orders
			if isspace(tdsls045.cwar) and
			   tdsls041.drct = tcyesno.no then
				|* Deliveries handled via Sales
				if tdsls045.ddat <> 0 then
					|* line = delivered
					l.procedure.mask(l.position;1) = "e"
				endif
			else
				|* Deliveries handled via warehousing
				l.procedure.mask(l.position;1) = "n"
			endif
			break
		case "tdsls4247m000":
		     |* release to invoicing
			if set.release.to.invoicing.to.executed() then
				l.procedure.mask(l.position;1) = "e"
			endif
			break
		endcase
	endfor
	return(l.procedure.mask)
}

function domain	tcbool set.release.to.warehousing.to.executed()
{
	domain	bcstc.lng2	l.activity.number.mcs039

	if generate.freight.order() = tcyesno.yes and
	   tdsls045.torn = 0 then
	   	|* If a freight order needs to be generated for the sales order
		|* the release to warehousing activity must not be set executed.
		|* First generate the freight order then the order can be
		|* released.
		return(false)
	endif

	if tdsls041.opol = tcittc.make.customized then
		|* The sales order line is not yet customized. Customize the
		|* the order line before the line is release to warehousing.
		|* The activity cannot be set to executed.
		return(false)
	endif

	|* Generate order commitment
	if activity.present.in.order.procedure("tdinv2201m000",
						l.activity.number.mcs039) then
		if tdsls045.ssls <> 0 and
		   tdsls045.ssls <= tcmcs042.stno(l.activity.number.mcs039) then
			|* generate inventory commitment is part of the order
			|* procedure but not executed. If so then release to
			|*  warehousing can also not set to executed.
			return(false)
		endif
	endif

	return(true)
}

|* This section is disabled because for the current version cisli was not able
|* to convert sales order line ready for "Print sales invoice" to cisli with
|* status confirmed. This will be available in a next version.
|function domain tcbool set.release.to.invoicing.to.executed()
|{
|	domain	tcsess	l.next.activity.on.source.side
|	domain	tcbool	l.release.to.invoicing.done
|
|	|* Initialize
|	l.next.activity.on.source.side = ""
|
|	|* get the activitycode from the activity array when the next acitivity
|	|* on the source side is specified.
|	if tdsls045.ssls <> 0 then
|		l.next.activity.on.source.side =
|			g.old.session.code.activities.array(1,tdsls045.ssls)
|	endif
|
|	on case strip$(l.next.activity.on.source.side)
|	case "tdsls4404m000":
|	|* Print sales invoice
|	case "tdsls4435m000":
|	|* Print proforma invoices
|	case "tfcmg6200m000":
|	|* Link advance receipts for profo
|	case "tdsls4223m000":
|	|* Process delivered sales orders
|		l.release.to.invoicing.done = true
|		break
|	default:
|		l.release.to.invoicing.done = false
|		break
|	endcase
|	return(l.release.to.invoicing.done)
|}
function domain tcbool set.release.to.invoicing.to.executed()
{
	domain	tcsess	l.next.activity.on.source.side

	|* get the activitycode from the activity array when the next acitivity
	|* on the source side is specified.
	if tdsls045.ssls <> 0 then
		l.next.activity.on.source.side =
			g.old.session.code.activities.array(1,tdsls045.ssls)
	endif

	if strip$(l.next.activity.on.source.side) = "tdsls4223m000" then
		|* It can be possible that the invoice number is zero but the
		|* line is already processed. Order qty is completely taken
		|* as backorder qty -> Nothing delivered -> no invoice -> line
		|*processed
		return(true)
	endif

	if tdsls045.invn = 0 then
		|* Invoice not yet printed -> release still required
		return(false)
	endif
	return(true)
}

|*****************************************
|*  Retrieve order acknowledgement related fields
|*****************************************
 function domain tcmcs.str8 get.change.order.sequence.number ()
 {
 	 read.sales.order.change.codes ()
 	 return ( tdsls703.cosn )
 }

 function domain tccdis get.change.reason ()
 {
 	 read.sales.order.change.codes ()
 	 return ( tdsls703.crcd )
 }

 function domain tccdis get.change.type ()
 {
 	 read.sales.order.change.codes ()
 	 return ( tdsls703.ctcd )
 }

 function domain tcmcs.str2 get.acknowledgement.code ()
 {
 	 read.sales.order.change.codes ()
 	 return ( tdsls703.akcd )
 }

 function read.sales.order.change.codes ()
 {
 	 static domain 	tcorno 	 	s.order
	 static domain	tcpono		s.position
 	| * To prevent too much read actions.
 	 if s.order = tdsls045.orno and
	    s.position = tdsls045.pono then
 	 	 return
 	 else
 	 	 s.order = tdsls045.orno
		 s.position = tdsls045.pono
 	 endif
 	| * Only the values are read that are needed for conversion.
 	 select 	 tdsls703.cosn,
 	 	 tdsls703.crcd,
 	 	 tdsls703.ctcd,
 	 	 tdsls703.akcd
 	 from 	 tdsls703
 	 where 	 tdsls703._index1 = { 	 :tdsls045.orno,
 	 	 	 	 	 :tdsls045.pono}
 	 as set with 1 rows
 	 selectdo
 	 selectempty
 	 	 tdsls703.cosn = ""
 	 	 tdsls703.crcd = ""
 	 	 tdsls703.ctcd = ""
 	 	 tdsls703.akcd = ""
 	 endselect
 }

function domain	bcpsty get.default.sales.type()
{
	static	domain	bcpsty	s.default.sales.type		fixed

	if not isspace (s.default.sales.type) then
		return(s.default.sales.type)
	endif

	|*s.default.sales.type filled with bcstc020.type
	g.ret = get.default.sls.type.for.tfacr(
					s.default.sales.type,
					g.error.message)
	return(s.default.sales.type)
}


function domain bccost get.cost.component()
{
	static	domain	bccost	s.new.cost.component	fixed
	static	domain	bccpcp	s.old.cost.component	fixed

	if s.old.cost.component <> tdsls045.cpcp then

		|* makes table bcstc006 current
		g.ret = get.cost.components(
				bcorig.ticpr,
				tdsls045.cpcp,
				"",
				g.error.message)
		s.new.cost.component = bcstc006.cost
		s.old.cost.component = tdsls045.cpcp
	endif

	return(s.new.cost.component)
}

|****************************************
|* functions for tdsls402
|****************************************
								|#800-143063.sn
function domain tcpono	get.original.sequence()
{
	domain	tcpono	l.original.sequence

	l.original.sequence = 0
	l.original.sequence = get.sls.order.line.sequence.number(
				tdsls045.orno,
				tdsls045.pono,
				tdsls045.srnb)

	return(l.original.sequence)
}
								|#800-143063.en

function domain	bcorno	get.purchase.order()
{
	static	domain	tcorno	s.old.purchase.order
	static	domain	bcorno	s.new.purchase.order	fixed

	if s.old.purchase.order <> tdsls041.porn then
		s.old.purchase.order = tdsls041.porn
		if tdsls041.porn <> 0 then
			s.new.purchase.order = convert.number(
							bcckon.act.pur,
							tdsls041.porn)
		else
			s.new.purchase.order = ""
		endif
	endif
	return(s.new.purchase.order)
}

function domain	bcorno	get.quotation.order()
{
	static	domain	tcorno	s.old.quotation.order
	static	domain	bcorno	s.new.quotation.order	fixed

	if s.old.quotation.order <> tdsls041.qono then
		s.old.quotation.order = tdsls041.qono
		if tdsls041.qono <> 0 then
			s.new.quotation.order = convert.number(
							bcckon.sls.quot,
							tdsls041.qono)
		else
			s.new.quotation.order = ""
		endif
	endif
	return(s.new.quotation.order)
}


function domain tcsrnb get.linked.purchase.order.line.sequence()
{
	if tdsls041.porn = 0 then
		return(0)
	endif

	if not isspace(tdsls045.cwar) then
		|* For cross docking orders the purchase sequence
		|* number is not stored in the linked order line
		|* data.
		return(0)
	endif

	|* For direct delivery orders the purchase and the sales
	|* sequences are not the same.
	return(tdsls045.srnb + 1)
}

function domain	tdsls.altn get.quotation.alternative()
{
	domain tdsls.altn	l.alternative

	l.alternative = 0

	if tdsls041.qono <> 0 then
		select	tdsls002.srnb:l.alternative
		from	tdsls002
		where	tdsls002._index1 = {:tdsls041.qono, :tdsls041.qpon}
		and	tdsls002.lsta = tdsls.lsta.processed
		as set with 1 rows
		selectdo
		selectempty
			|* Check in the quotation history
			select	tdsls011.srnb:l.alternative
			from	tdsls011
			where	tdsls011._index1 = {:tdsls041.qono,
						    :tdsls041.qpon}
			and	tdsls011.lsta = tdsls.lsta.processed
			as set with 1 rows
			selectdo
			endselect
		endselect
	endif
	return(l.alternative)
}

function long get.purchase.order.approved()
{
	if tdsls041.porn <> 0 then
		return(target(tcyesno.yes))
	else
		return(target(tcyesno.no))
	endif
}

function domain tcbool	clusters.records.available.for.order.lines()
{
	static		string	s.source.cluster(10)	fixed
	static	domain	tcbool	s.clusters.checked

	if s.clusters.checked then
		if not isspace(s.source.cluster) then
			return(true)
		else
			return(false)
		endif
	endif

	select	tssma102.cloc,
		tssma102._index8
	from 	tssma102
	where	tssma102.orno <> 0
	and	tssma102.pono <> 0
	order by tssma102._index8
	as set with 1 rows
	selectdo
		s.source.cluster = tssma102.cloc
	endselect

	s.clusters.checked = true
	if not isspace(s.source.cluster) then
		return(true)
	endif
	return(false)
}

function string get.purchase.order.date()
{
	|* This function reads the purchase order date
	if tdsls041.porn <> 0 then
		read.linked.purchase.order.data()
		return(get.utc(tdpur041.odat))
	endif
	return(utc(0,0))
}

function domain tcqsl1 get.received.purchase.quantity()
{
	domain	tcqsl1 l.received.quantity.in.inventory.unit

	l.received.quantity.in.inventory.unit = 0.0

	if tdsls041.porn = 0 then
		return(l.received.quantity.in.inventory.unit)
	endif

	|* Received pur quantity equals the delivered quantity on the sales
	|* order line delivery.
	l.received.quantity.in.inventory.unit =
			quantity.from.order.unit.to.inventory.unit(
								tdsls045.dqua)

	return(l.received.quantity.in.inventory.unit)
}

function read.linked.purchase.order.data()
{
	static	domain	tcorno	s.purchase.order
	static	domain	tcpono	s.purchase.order.position

	|* This function reads all required data from the purchase order linked
	|* to the sales order line

	if s.purchase.order = tdsls041.porn and
	   s.purchase.order.position = tdsls041.ppon then
		return
	else
		s.purchase.order = tdsls041.porn
		s.purchase.order.position = tdsls041.ppon
	endif

	select 	tdpur041.odat
	from	tdpur041
	where	tdpur041._index1 = {:tdsls041.porn, :tdsls041.ppon}
	as set with 1 rows
	selectdo
	selectempty
		|* If the Purchase order cannot be found set the purchase order
		|* date to 0
		tdpur041.odat = 0
	endselect
	return
}

function string get.service.cluster()
{
			string	l.source.cluster(10)
	static	domain	tcorno	s.order
	static	domain	tcpono	s.position
	static 	domain	bcstr8	s.target.cluster	fixed

	l.source.cluster = ""

	if not clusters.records.available.for.order.lines() then
		return(l.source.cluster)
	endif

	if s.order = tdsls045.orno and
	   s.position = tdsls045.pono then
		return(s.target.cluster)
	else
		s.order = tdsls045.orno
	   	s.position = tdsls045.pono
	endif

	s.target.cluster = ""

	select	tssma102.cloc:l.source.cluster
	from 	tssma102
	where 	tssma102._index8 = {:tdsls041.orno, :tdsls041.pono}
	as set with 1 rows
	selectdo
	endselect
	g.ret = get.configuration(l.source.cluster, g.error.message)
	s.target.cluster = bcsts005.clst

	return(s.target.cluster)
}

function domain	tccwar	get.purchase.order.advice.warehouse()
{
	domain	tcorno	l.planned.purchase.order
	domain	tccwar	l.planned.purchase.order.cwar	fixed

  	read.purchase.order.advice(
					tdsls045.orno,
					tdsls045.pono,
					l.planned.purchase.order,
					l.planned.purchase.order.cwar)

	|* if purchase order advice is not present -> cwar empty
	|* else cwar is taken from tdinv310.cwar
	return(l.planned.purchase.order.cwar)
}

function double get.tdsls401.copr(
			long	i.element)
{
		double	l.cost.amnt

	l.cost.amnt = fill.mc.field.double(tdsls045.copr, i.element)

	return(tdsls041.oqua * tdsls041.cvqs * l.cost.amnt)
}

|****************************************
|* functions for tdsls406
|****************************************
function long	get.linked.to.contract()
{
	if tdsls041.cono <> 0 then
		return(target(tcyesno.yes))
	endif
	return(target(tcyesno.no))
}
								|#SP1.sn
function dump.actual.delivery()
{
	dump 3 | *  tdsls406 Actual delivery
	if not isspace(g.lot.and.serial.set) then
		|* dump lot and serial set.
		dump 4	|* Lot and serial set
		dump 5	|* lot and serial set details
	endif
	determine.cogs.and.dump()
	dump 6	|* Actual delivery line cogs
}
								|#SP1.en

								|#SP1.sn
function string get.lot.and.serial.set.406()
{
	|* The lot and serial set is already determined with function
	|* get.lot.and.serial.set.401(). in this function the global variable
	|* g.lot.and.serial.set is filled (or empty). If the variable has a
	|* value then this function handles the dumping of the tcibd410 and
	|* tcibd411 tables.
	|* 1) Dump tdsls401 -> detemine g.lot.and.serial.set
	|* 2) dump tdsls406
	|* 3) if lot.and.serial.set then dump tcibd410, tcibd411
	return(g.lot.and.serial.set)
}
								|#SP1.en
								|#SP1.sn
function domain tdltc.clot get.serial.tcibd411()
{
	if item.is.serialized() then
		if g.ilc.implemented then
			|* delivered tdilc401 record selected
			return(tdilc401.clot)
		else
			return(tdsls041.clot)
		endif
	endif
	return("")
}
								|#SP1.en
								|#SP1.sn
function domain tdltc.clot get.lot.tcibd411()
{
	if item.is.lot.controlled() then
		if g.ilc.implemented then
			|* delivered tdilc401 record selected
			return(tdilc401.clot)
		else
			return(tdsls041.clot)
		endif
	endif
	return("")
}
								|#SP1.en
								|#SP1.sn
function domain	tccuni	get.inventory.unit()
{
	get.item.inventory.unit.and.price.group()
	return(g.inventory.unit)
}
								|#SP1.en

								|#SP1.sn
|****************************************
|* functions for tdsls409
|****************************************

function determine.cogs.and.dump()
{
	|*********************************************
	|* Same kind of logic is used in migration object whinr110.
	|* If changes to this function (or sub function) is required then
	|* verify if the changes are also needed in WH
	|*********************************************

	domain	tdltc.clot l.source.lotcode

 	if tdsls041.opol = tcittc.customized then
 		|* Item is customized use customized item cost prices
		l.source.lotcode = get.lot.tcibd411()
		if isspace(l.source.lotcode) then
 			l.source.lotcode = get.serial.tcibd411()
 		endif
 		get.customized.cost.price(tdsls045.item,
 			      		  l.source.lotcode,
 			      		  tdsls045.dqua)
		return
 	endif

	if not isspace(g.lot.and.serial.set) then
		read.item.data()
		if g.inventory.valuation = tcstva.lot.price then
	 		|* Lotcontrolled or serialized then use lotprice if
	 		|* inventory valuation is not FTP
	 		l.source.lotcode = get.lot.tcibd411()
	 		if isspace(l.source.lotcode) then
	 			l.source.lotcode = get.serial.tcibd411()
	 		endif

	 		get.lot.price(tdsls045.item,
	 			      l.source.lotcode,
	 			      tdsls045.dqua)
			return
		endif
	endif

	get.standard.cost.price(tdsls045.item, tdsls045.dqua, tdsls045.ddat)

}

function get.standard.cost.price(domain	tcitem	i.item,
				 domain	tcqiv1	i.delivery.quantity,
				 domain	tcdate	i.delivery.date)
{
			long		l.result
			long		i
		domain	tcdate		l.hold.date
		domain	tcbool		l.set.date
		domain	tcamnt		l.hold.amnt(3)
		domain	bccost		l.detail.cost.component
	static	domain	bccost		l.material.component
	static	domain	bccost		l.operation.component
	static	domain	bccost		l.surcharge.component
	static	domain	tcamnt		l.material.component.amnt(3)
	static	domain	tcamnt		l.operation.component.amnt(3)
	static	domain	tcamnt		l.surcharge.component.amnt(3)

	|* initialize
 	e = set.mem(l.material.component.amnt, 0.0)
 	e = set.mem(l.operation.component.amnt, 0.0)
 	e = set.mem(l.surcharge.component.amnt, 0.0)
	l.set.date = true

	|* Select cost record
	select	ticpr300.*
 	from	ticpr300
 	where	ticpr300._index1 =  {:i.item}
	and	ticpr300.cntr = ""
	and	ticpr300.indt <= :i.delivery.date
	order by ticpr300.indt desc
	selectdo
  	 	if l.set.date then
  	 		l.set.date = false
  	 		l.hold.date = ticpr300.indt
  	 	else
  	 		if ticpr300.indt <> l.hold.date then
  	 			|* only handle ticpr300 records for the same
  	 			|* date
  	 			break
  	 		endif
 		endif

		|* handle cost component conversion for the record
  	 	for i =  1 to g.mc.depth
  	 		l.hold.amnt(i) =  get.amount.per.cost.component(
							"ticpr300", i)
  	 	endfor

 	   	analyze.cost.component(	i.item,
 	   	   	   	   	"",
 	   	   	   	   	ticpr300.cpcp,
 	   	   	   	   	l.detail.cost.component,
 	   	   	   	   	l.material.component,
 	   	   	   	   	l.operation.component,
 	   	   	   	   	l.surcharge.component,
 	   	   	   	   	l.result)

		handle.analyze.cost.component.result(
					l.result,
					l.detail.cost.component,
					l.hold.amnt,
					i.delivery.quantity,
					l.material.component.amnt,
					l.operation.component.amnt,
					l.surcharge.component.amnt)
	selectempty
		analyze.cost.component( i.item,
 	   	   	   	   	"",
 	   	   	   	   	"",
 	   	   	   	   	l.detail.cost.component,
 	   	   	   	   	l.material.component,
 	   	   	   	   	l.operation.component,
 	   	   	   	   	l.surcharge.component,
 	   	   	   	   	l.result)
	endselect

	handle.dump.aggregated.cost.components(
					l.material.component,
					l.operation.component,
					l.surcharge.component,
					l.material.component.amnt,
					l.operation.component.amnt,
					l.surcharge.component.amnt,
					i.delivery.quantity)
}

function handle.analyze.cost.component.result(
				long	i.result,
			domain	bccost	i.detail.cost.component,
		ref	domain	tcamnt	i.hold.amnt(),
			domain	tcqiv1	i.delivery.quantity,
		ref	domain	tcamnt	io.material.component.amnt(),
		ref	domain	tcamnt	io.operation.component.amnt(),
		ref	domain	tcamnt	io.surcharge.component.amnt())
{

	long		i


	on case i.result
   	case 0:
	|* Cost Component in chart
	|* Detail Cost Component
		g.cost.component = i.detail.cost.component
		for i =  1 to g.mc.depth
			g.cogs.amnt(i) = i.hold.amnt(i) * i.delivery.quantity
		endfor
		dump 6	|* Actual delivery line cogs
		break
	case 1:
	|* Merge to aggregated material cost component
		for i =  1 to g.mc.depth
   	   		io.material.component.amnt(i) =
   	   	   		io.material.component.amnt(i) +	i.hold.amnt(i)
		endfor
		break
	case 2:
	|* Merge to aggregated operation cost component
		for i =  1 to g.mc.depth
   		   	io.operation.component.amnt(i) =
   	   	   		io.operation.component.amnt(i) + i.hold.amnt(i)
		endfor
   	   	break
	case 3:
   	|* Merge to aggregated surcharge cost component
		for i =  1 to g.mc.depth
			io.surcharge.component.amnt(i) =
   	   	   		io.surcharge.component.amnt(i) + i.hold.amnt(i)
		endfor
   	   	break
	endcase
}

function handle.dump.aggregated.cost.components(
			domain	bccost	i.material.component,
			domain	bccost	i.operation.component,
			domain	bccost	i.surcharge.component,
		ref	domain	tcamnt	i.material.component.amnt(),
		ref	domain	tcamnt	i.operation.component.amnt(),
		ref	domain	tcamnt	i.surcharge.component.amnt(),
			domain	tcqiv1	i.delivery.quantity)
{

	long		i

	|* Material Cost Component
	g.cost.component = i.material.component
	for i =  1 to g.mc.depth
		g.cogs.amnt(i) = i.material.component.amnt(i) *
							i.delivery.quantity
	endfor
	dump 6	|* Actual delivery line cogs

	|* Operation Cost Component
	g.cost.component = i.operation.component
	for i =  1 to g.mc.depth
		g.cogs.amnt(i) = i.operation.component.amnt(i) *
							i.delivery.quantity
	endfor
	dump 6	|* Actual delivery line cogs

	|* Surcharge Cost Component
	g.cost.component = i.surcharge.component
	for i =  1 to g.mc.depth
		g.cogs.amnt(i) = i.surcharge.component.amnt(i) *
				 			i.delivery.quantity
	endfor
	dump 6	|* Actual delivery line cogs
}



function get.lot.price(		domain	tcitem		i.item,
				domain	tdltc.clot	i.clot,
				domain	tcqiv1		i.delivery.quantity)
{
		long	l.result
		long	i

	domain	bccost	l.material.component
	domain	bccost	l.operation.component
	domain	bccost	l.surcharge.component
	domain	tcamnt	l.material.component.amnt(3)
	domain	tcamnt	l.operation.component.amnt(3)
	domain	tcamnt	l.surcharge.component.amnt(3)
	domain	tcamnt	l.hold.amnt(3)
	domain	bccost	l.detail.cost.component

	e = set.mem(l.material.component.amnt, 0.0)
	e = set.mem(l.operation.component.amnt, 0.0)
	e = set.mem(l.surcharge.component.amnt, 0.0)

	select	tdltc004.*
	from	tdltc004
	where	tdltc004._index1 =  { 	 :i.item,
 	 	 	 	 	 "",
 	  	  	 	 	 :i.clot}
	selectdo
		for i =  1 to g.mc.depth
 	  		l.hold.amnt(i) = get.amount.per.cost.component(
 	  						 "tdltc004",
 	  						 i)
 	 	endfor

		analyze.cost.component( tdltc004.item,
 	  	 	 	 	"",
 	  	 	 	 	tdltc004.cpcp,
 	  	 	 	 	l.detail.cost.component,
 	  	 	 	 	l.material.component,
 	  	 	 	 	l.operation.component,
 	  	 	 	 	l.surcharge.component,
 	  	 	 	 	l.result)

		handle.analyze.cost.component.result(
					l.result,
					l.detail.cost.component,
					l.hold.amnt,
					i.delivery.quantity,
					l.material.component.amnt,
					l.operation.component.amnt,
					l.surcharge.component.amnt)
	endselect

	handle.dump.aggregated.cost.components(
					l.material.component,
					l.operation.component,
					l.surcharge.component,
					l.material.component.amnt,
					l.operation.component.amnt,
					l.surcharge.component.amnt,
					i.delivery.quantity)
}

function get.customized.cost.price(	domain	tccprj	i.cprj,
					domain	tcitem	i.item,
					domain	tcqiv1	i.delivery.quantity)
{
			long	l.result
			long	i
		domain	bccost	l.detail.cost.component
		domain	tcamnt	l.hold.amnt(3)
	static	domain	bccost	l.material.component
	static	domain	bccost	l.operation.component
	static	domain	bccost	l.surcharge.component
	static	domain	tcamnt	l.material.component.amnt(3)
	static	domain	tcamnt	l.operation.component.amnt(3)
	static	domain	tcamnt	l.surcharge.component.amnt(3)

	|* Initialize
 	e = set.mem(l.material.component.amnt,  0.0)
 	e = set.mem(l.operation.component.amnt, 0.0)
 	e = set.mem(l.surcharge.component.amnt, 0.0)

	select	tipcs350.*
 	from	tipcs350
 	where	tipcs350._index1 =  {:i.cprj, :i.item}
 	selectdo
		for i =  1 to g.mc.depth
			l.hold.amnt(i) =  get.amount.per.cost.component(
							"tipcs350",
							i)
  	 	 endfor
		analyze.cost.component( i.item,
 	   	   	   	   	i.cprj,
 	   	   	   	   	tipcs350.cpcp,
 	   	   	   	   	l.detail.cost.component,
 	   	   	   	   	l.material.component,
 	   	   	   	   	l.operation.component,
 	   	   	   	   	l.surcharge.component,
 	   	   	   	   	l.result)

		handle.analyze.cost.component.result(
					l.result,
					l.detail.cost.component,
					l.hold.amnt,
					i.delivery.quantity,
					l.material.component.amnt,
					l.operation.component.amnt,
					l.surcharge.component.amnt)
	selectempty
		analyze.cost.component( i.item,
					i.cprj,
					"",
					l.detail.cost.component,
					l.material.component,
					l.operation.component,
					l.surcharge.component,
					l.result)
	endselect

	handle.dump.aggregated.cost.components(
					l.material.component,
					l.operation.component,
					l.surcharge.component,
					l.material.component.amnt,
					l.operation.component.amnt,
					l.surcharge.component.amnt,
					i.delivery.quantity)
}
								|#SP1.en





|* End of script **************************************************************
:FUNC:END
:TEXT:

:TEXT:END
FUNC160
:MPRF:19
:VERS:B40U
:RELE:c4
:CUST:cont
:TCPAC:td
:TCMOD:sls
:TFLNO:451
:FUNC:START
function read.sales.order.header.history()
{
	if tdsls050.orno = tdsls051.orno and
	   ((tdsls050.trdt = tdsls051.trdt and
	     tdsls050.trtm <= tdsls051.trtm) or
	    tdsls050.trdt < tdsls051.trdt) then
	    	return
	endif

	select	tdsls050._index1, tdsls050.comp, tdsls050.scom,
		tdsls050.cfrw, tdsls050.cper, tdsls050.cotp,
		tcmcs042.casi
	from	tdsls050, tcmcs042
	where	tdsls050._index1 = {:tdsls051.orno}
	and	((tdsls050.trdt = :tdsls051.trdt and
		  tdsls050.trtm <= :tdsls051.trtm) or
		 tdsls050.trdt < :tdsls051.trdt)
	and	tdsls050.cotp refers to tcmcs042 unref clear
	order by tdsls050._index1 desc
	as set with 1 rows
	selectdo
		|* The last recorded record is read which is inserted on or
		|* just before the line was inserted into history.
	endselect
}

function string convert.sales.order()
{
	static	domain	bcorno	s.orno		fixed
	static	domain	tcorno	s.sls051.orno

	if s.sls051.orno <> tdsls051.orno then
		s.sls051.orno = tdsls051.orno
		s.orno = convert.number(bcckon.act.sls, tdsls051.orno)
	endif

	return(s.orno)
}

function long convert.serial.number()				|#IDX-ERR.sn
{
	if tdsls051.ckor = 2 then
		|* In Baan 6 the record type (tdsls451.ckor) is
		|* missing in the indices 6 and 7. For normal order
		|* handling these indices are unique due to the way
		|* tdsls451.sern is filled in Baan 6. During the
		|* migration a duplicate record error can occur when
		|* an order line is cancelled. In that case an intake
		|* record and a cancellation record are inserted,
		|* both with tdsls051.sern is 0 and sometimes both
		|* with the same transaction date and time.
		|* For this situation the sern is raised with 10 for
		|* the cancellation record to avoid duplicate
		|* records for the indices 6 and 7.
		return(tdsls051.sern + 10)
	endif

	return(tdsls051.sern)
}								|#IDX-ERR.en

function domain bcstc.bpid convert.business.partner()
{
	static	domain	bcstc.bpid	s.business.partner	fixed
	static	domain	tccuno		s.sls051.cuno

	if s.sls051.cuno <> tdsls051.cuno then
		s.sls051.cuno = tdsls051.cuno
		s.business.partner = get.business.partner.code(
					tdsls051.cuno,
					bcstc.orgn.cuno,
					g.error.mess)
	endif

	return(s.business.partner)
}

function domain bcstc.ccnt convert.ship.to.contact()
{
		domain	bcstc.keys	l.key 	 	fixed
	static	domain	bcstc.ccnt	s.contact	fixed
	static	domain	tdsmi.cper	s.sls050.cper	fixed

	l.key = ""

	if isspace(tdsls050.cper) then
		s.contact = ""
		s.sls050.cper = ""
		return(s.contact)
	endif

	if s.sls050.cper <> tdsls050.cper then
		l.key(1;6) = tdsls051.cuno
		l.key(7;6) = tdsls050.cper
		if get.cross.reference.for.contact.code(
					"tdsmi120",
					l.key,
					g.error.mess) = 0 then
			s.contact = bcstc005.ccnt
		endif
		s.sls050.cper = tdsls050.cper
	endif

	return(s.contact)
}

function domain bcitem convert.item()
{
	static	domain	tcittc		s.sls051.opol
	static	domain	tccprj		s.sls051.cprj
	static	domain	tcitem		s.sls051.item
	static	domain	bcitem		s.new.item	fixed
		domain	bcstc.nprj	l.project	fixed

	if s.sls051.opol <> tdsls051.opol or
	   s.sls051.cprj <> tdsls051.cprj or
	   s.sls051.item <> tdsls051.item then
	   	s.sls051.opol = tdsls051.opol
		s.sls051.cprj = tdsls051.cprj
		s.sls051.item = tdsls051.item

		if tdsls051.opol = tcittc.customized then
			l.project = get.ti.project(tdsls051.cprj)
		else
			l.project = ""
		endif

		s.new.item = segment.item.code(tdsls051.item, l.project)
	endif

	return(s.new.item)
}

function long convert.product.variant()
{
			long	l.ret
	static	domain	tccpva	s.sls051.cpva		fixed
	static	domain	bccpvl	s.new.product.variant

	if isspace(tdsls051.cpva) then
		return(0)
	endif

	if s.sls051.cpva = tdsls051.cpva then
		return(s.new.product.variant)
	endif

	s.sls051.cpva = tdsls051.cpva

	l.ret = get.new.product.variant(tdsls051.cpva, g.error.mess)
	s.new.product.variant = bcsti001.cpvl

	return(s.new.product.variant)
}

function convert.tax()
{
			long	l.ret
	static	domain	tcccty	s.sls051.ccty	fixed
	static	domain	tccvat	s.sls051.cvat	fixed

	if s.sls051.ccty <> tdsls051.ccty or
	   s.sls051.cvat <> tdsls051.cvat then
	   	l.ret = get.tax.by.country.code(
				tdsls051.ccty,
				tdsls051.cvat,
				var.tdsls451.ccty,
				var.tdsls451.cvat,
				g.error.mess)
		s.sls051.ccty = tdsls051.ccty
	   	s.sls051.cvat = tdsls051.cvat
	endif
}

function long get.make.customized()
{
	if tdsls051.opol = tcittc.make.customized then
		return(target(tcyesno.yes))
	endif

	return(target(tcyesno.no))
}

function domain tcqsl1 convert.delivered.quantity()
{
	|* tdsls451.qidl is filled with tdsls051.qana after being converted
	|* into the inventory unit of the item.

		domain	tccuni	l.inventory.unit
	static	domain	tcqsl1	s.qty.in.inv.unit
	static	domain	tcitem	s.sls051.item
	static	domain	tccprj	s.sls051.cprj
	static	domain	tcittc	s.sls051.opol

	if s.sls051.item <> tdsls051.item or
	   s.sls051.cprj <> tdsls051.cprj or
	   s.sls051.opol <> tdsls051.opol then
		s.sls051.item = tdsls051.item
	   	s.sls051.cprj = tdsls051.cprj
	   	s.sls051.opol = tdsls051.opol
		l.inventory.unit = get.item.inventory.unit()

		s.qty.in.inv.unit = itccom0007.qty.domain.round(
				(tdsls051.qana * tdsls051.cvqs),
				"tcqsl1",
				l.inventory.unit)
	endif

	return(s.qty.in.inv.unit)
}

function domain tccuni convert.quantity.unit()
{
	if tdsls051.ckor = 1 or
	   tdsls051.ckor = 2 then
	   	return(tdsls051.cuqs)
	endif

	return(get.item.inventory.unit())
}

function domain tcconv convert.factor.sls.unit.to.inv.unit()
{
	if tdsls051.ckor = 1 or
	   tdsls051.ckor = 2 then
	   	return(tdsls051.cvqs)
	endif

	return(1.0)
}

function domain tccuni get.item.inventory.unit()
{
	|* For customized items the inventory unit is retrieved from tipcs021.
	|* For non-customized items the inventory unit is retrieved from
	|* tiitm001.

	domain	tccuni	l.inventory.unit

	l.inventory.unit = ""

	if not isspace(tdsls051.cprj) and
	   tdsls051.opol = tcittc.customized then
	   	select	tipcs021.cuni:l.inventory.unit
		from	tipcs021
		where	tipcs021._index1 = {:tdsls051.cprj, :tdsls051.item}
		as set with 1 rows
		selectdo
		endselect
	else
		select	tiitm001.cuni:l.inventory.unit
		from	tiitm001
		where	tiitm001._index1 = {:tdsls051.item}
		as set with 1 rows
		selectdo
		endselect
	endif

	return(l.inventory.unit)
}

function domain bcstd.fent convert.contract.office()
{
			long		l.ret
		domain	bcstd.fent	l.office	fixed
	static	domain	tcncmp		s.sls050.comp

	if tdsls051.cono = 0 then
		l.office = ""
		s.sls050.comp = 0
		return(l.office)
	endif

	if s.sls050.comp <> tdsls050.comp then
		s.sls050.comp = tdsls050.comp
		l.ret = get.enterprise.unit(
				tdsls050.comp,
				get.compnr(),
				g.error.mess)
	endif

	return(bcstc018.sofd)
}

function long convert.shipping.constraint()
{
	if tdsls050.scom = tcyesno.yes then
		return(target(tdscon.oc))
		|* Ship Order Complete
	endif

	if tdsls051.scom = tcyesno.yes then
		return(target(tdscon.sc))
		|* Ship Line Complete
	endif

	return(target(tdscon.none))
}

function domain bccadr convert.address()
{
	static	domain	bccadr	s.address	fixed
	static	domain	tcorno	s.sls051.orno
	static 	domain	tcpono	s.sls051.pono

	if s.sls051.orno <> tdsls051.orno or
	   s.sls051.pono <> tdsls051.pono then
		s.sls051.orno = tdsls051.orno
		s.sls051.pono = tdsls051.pono
		s.address = convert.sales.address(
				tdsls051.cdel,
				tdsls051.cuno,
				tdsls051.orno,
				tdsls051.pono,
				0)	|* address type: delivery address
	endif

	return(s.address)
}

function long convert.delivery.type()
{
	if tdsls051.drct = tcyesno.yes then
		return(target(tdsls.dltp.direct.delivery))
	endif

	if tdsls051.porn <> 0 then
		return(target(tdsls.dltp.cross.docking))
	endif

	return(target(tdsls.dltp.warehousing))
}

function domain tcmcs.str2 get.acknowledgment.code()
{
	|* Only the value is read that is needed for conversion; when
	|* there are more than one records present for the order

	|* line, then the latest record is taken that is created
	|* before the order line history transaction date.

	static	domain	tcmcs.str2	s.acknowl.code fixed
	static	domain	tcorno		s.order
	static	domain	tcpono		s.position

	if s.order = tdsls051.orno and
	   s.position = tdsls051.pono and
	   ((tdsls704.date = tdsls051.trdt and
	     tdsls704.time <= tdsls051.trtm) or
	    tdsls704.date < tdsls051.trdt) then
		return(s.acknowl.code)
		|* last retrieved record is also actual for this request
	else
		s.order = tdsls051.orno
		s.position = tdsls051.pono
		s.acknowl.code = ""
	endif

	select	tdsls704.akcd:s.acknowl.code, tdsls704._index1
	from	tdsls704
	where	tdsls704._index1 = {	:tdsls051.orno,
					:tdsls051.pono}
	and	((tdsls704.date = :tdsls051.trdt and
		  tdsls704.time <= :tdsls051.trtm) or
		 tdsls704.date < :tdsls051.trdt)
	order by tdsls704._index1 desc
	as set with 1 rows
	selectdo
	endselect

	return(s.acknowl.code)
}

function long get.price.origin()
{
	if not double.cmp(tdsls051.qana, 0.0, 0.0001) then
		return(target(tdgen.porg.not.applicable))
	endif

	on case tdsls051.plev
	case tdplev.contract:
		return(target(tdgen.porg.contract))
	case tdplev.cust.item:
	case tdplev.plst.item:
		return(target(tdgen.porg.price.structure))
	case tdplev.ilst:
		return(target(tdgen.porg.def.pr.book))
	case tdplev.item:
		return(target(tdgen.porg.item.sls))
	case tdplev.not.def:
		return(target(tdgen.porg.not.applicable))
	default:
		break
	endcase

	return(target(tdgen.porg.manual))
}

function long get.discount.origin(long	i.element)
{
	if not double.cmp(tdsls051.pric, 0.0, 0.0001) then
		return(target(tdgen.dorg.not.applicable))
	else
		if not double.cmp(tdsls051.disc(i.element), 0.0, 0.0001) and
		   not double.cmp(tdsls051.ldam(i.element), 0.0, 0.0001) then
		   	return(target(tdgen.dorg.not.applicable))
		endif
	endif

	on case tdsls051.dlev(i.element)
	case tddlev.contract:
		return(target(tdgen.dorg.contract))
	case tddlev.cust:
	case tddlev.cust.item:
	case tddlev.cust.pgrp:
	case tddlev.plst:
	case tddlev.plst.item:
	case tddlev.plst.pgrp:
	case tddlev.ilst:
		return(target(tdgen.dorg.disc.structure))
	case tddlev.not.def:
		return(target(tdgen.dorg.not.applicable))
	default:
		break
	endcase

	return(target(tdgen.dorg.manual))
}

function domain bcstr9 get.price.matrix.definition()
{
		long		l.ret
	static	domain	tdplev	s.price.level
	static	domain	bcstr9	s.matrix.definition	fixed

	if not double.cmp(tdsls051.qana, 0.0, 0.0001) then
		return("")
	endif

	if s.price.level <> tdsls051.plev then
		s.price.level = tdsls051.plev
		l.ret = get.price.matrix.definition.sls(
				tdsls051.plev,
				s.matrix.definition,
				g.error.mess)
	endif

	return(s.matrix.definition)
}

function long get.discount.matrix.type(long	i.element)
{
	if not double.cmp(tdsls051.pric, 0.0, 0.0001) then
		|* No Price defined
		return(target(tdpcg.maty.none))
	endif

	if not double.cmp(tdsls051.disc(i.element), 0.0, 0.0001) and
	   not double.cmp(tdsls051.ldam(i.element), 0.0, 0.0001) then
		|* No discount percentage / amount defined.
		return(target(tdpcg.maty.none))
	endif

	if tdsls051.dlev(i.element) = tddlev.manual or
	   tdsls051.dlev(i.element) = tddlev.not.def then
		return(target(tdpcg.maty.none))
	endif

	return(target(tdpcg.maty.soldsc))
}

function domain bcstr9 get.discount.matrix.definition(long	i.element)
{
			long	l.ret
	static	domain	bcstr9	s.discount.matrix.definition	fixed
	static	domain	tddlev	s.discount.level

	if not double.cmp(tdsls051.pric, 0.0, 0.0001) then
		|* No Price defined
		return("")
	endif

	if not double.cmp(tdsls051.disc(i.element), 0.0, 0.0001) and
	   not double.cmp(tdsls051.ldam(i.element), 0.0, 0.0001) then
		|* No discount percentage / amount defined.
		return("")
	endif

	if s.discount.level <> tdsls051.dlev(i.element) then
		s.discount.level = tdsls051.dlev(i.element)
		l.ret = get.discount.matrix.definition.sls(
				tdsls051.dlev(i.element),
				s.discount.matrix.definition,
				g.error.mess)
	endif

	return(s.discount.matrix.definition)
}

function domain tccdsc get.discount.code(
				long	i.element)
{
	if not double.cmp(tdsls051.pric, 0.0, 0.0001) then
		|* No Price defined
		return("")
	endif

	if not double.cmp(tdsls051.disc(i.element), 0.0, 0.0001) and
	   not double.cmp(tdsls051.ldam(i.element), 0.0, 0.0001) then
		|* If no discount defined return None.
		return("")
	endif

	return(tdsls051.cdis(1, i.element))
}

function long convert.price.changes.allowed.after.delivery()
{
	if tdsls051.ddtb <> 0 and
	   tdsls051.invn = 0 then
		return(target(tcyesno.yes))
	endif

	return(target(tcyesno.no))
}

function long get.lot.selection()
{
	|* If lot control is lot by unit then lot is converted into a serial
	|* Serial will get lot code, serial selection is specific
	|* Lot is made empty and lot selection is any

	if isspace(get.warehouse()) then
		return(target(tclsel.any))
	endif

	if item.is.an.serialized.item() then
		return(target(tclsel.any))
	endif
	return(etol(tdsls051.lsel))
}

function domain tdltc.clot get.lot()
{
	|* See comments for function get.lot.selection()
	if isspace(get.warehouse()) then
		return("")
	endif

	if item.is.an.serialized.item() then
		return("")
	endif
	return(tdsls051.clot)
}

function long get.serial.selection()
{
	if isspace(get.warehouse()) then
		return(target(tdssel.any))
	endif

	if item.is.an.serialized.item() and
	   tdsls051.lsel = tclsel.specific then
		return(target(tdssel.specific))
	endif
	return(target(tdssel.any))
}

function domain tdltc.clot get.serial()
{
	|* See comments for function get.lot.selection()
	if isspace(get.warehouse()) then
		return("")
	endif

	if tdsls051.lsel = tclsel.any then
		return("")
	endif

	if item.is.an.serialized.item() then
		return(tdsls051.clot)
	endif
	return("")
}

function domain tcbool item.is.an.serialized.item()
{
	static	domain	tccprj	s.project		fixed
	static	domain	tcitem	s.item			fixed
	static	domain	tcbool	s.item.is.serialized

	if s.project <> tdsls051.cprj or
	   s.item <> tdsls051.item then
		s.item.is.serialized = serialized.item(
						tdsls051.cprj,
						tdsls051.item)
		s.project = tdsls051.cprj

		s.item = tdsls051.item
	endif
	return(s.item.is.serialized)
}

function domain tccwar	get.warehouse()
{
	if tdsls051.drct = tcyesno.yes then
		return("")
	else
		return(tdsls051.cwar)
	endif
}

function long get.inventory.handling()
{
	if tdsls051.isss = tcisss.issue.comp then
		return(target(tcinup.by.component))
	endif
	|* In all other cases issue by main item
	return(target(tcinup.by.main.item))
}

								|#203034.sn
|***************************************************************************
|* Convert cost prices (home cur/ inventory unit to
|* Cost amounts (in home cur/ inventory unit)
|***************************************************************************
function domain	tcamnt get.copr.amount( long i.index)
{
	domain	tcamnt	l.cost.amount

	l.cost.amount = fill.mc.field.double(tdsls051.copr, i.index) *
			qty.from.order.unit.to.inventory.unit(tdsls051.qana)
	return(l.cost.amount)
}

function domain	tcamnt get.fcop.amount( long i.index)
{
	domain	tcamnt	l.cost.amount

	l.cost.amount = fill.mc.field.double(tdsls051.fcop, i.index) *
			qty.from.order.unit.to.inventory.unit(tdsls051.qana)
	return(l.cost.amount)
}

function domain	tcamnt get.vcop.amount( long i.index)
{
	domain	tcamnt	l.cost.amount

	l.cost.amount = fill.mc.field.double(tdsls051.mcop, i.index) *
			qty.from.order.unit.to.inventory.unit(tdsls051.qana)
	return(l.cost.amount)
}

function domain tcqsl1 qty.from.order.unit.to.inventory.unit (
			domain	tcqrd1	i.quantity.in.order.unit )
{
 	 return ( itccom0007.qty.domain.round (
 	 	 	 i.quantity.in.order.unit * tdsls051.cvqs,
 	 	 	 "tcqsl1",
 	 	 	 get.item.inventory.unit()))
}

								|#203034.en
:FUNC:END
:TEXT:

:TEXT:END
FUNC160
:MPRF:19
:VERS:B40U
:RELE:c4
:CUST:cont
:TCPAC:tf
:TCMOD:cat
:TFLNO:221
:FUNC:START
|#203100.sn

function long get.highest.count.of.sern()
{
	itfgld0038.dim.rcd(tctcat215)
	itfgld0038.store.rcd.fields(tctcat215)

	select ctcat215.*
	from ctcat215
	where ctcat215._index1 = {:hold.ncmp,
				    :hold.dtyp,
				    :hold.dimx,
				    :hold.refu}
	selectdo
	selecteos
		sern.count = ctcat215.sern
	endselect

	itfgld0038.restore.rcd.fields(tctcat215)

	return(sern.count)
}			
				|#203100.en
:FUNC:END
:TEXT:

:TEXT:END
FUNC160
:MPRF:19
:VERS:B40U
:RELE:c4
:CUST:cont
:TCPAC:ti
:TCMOD:cpr
:TFLNO:000
:FUNC:START
|#CNT.sn
function domain tcyesno include.fixed.costs(
			domain	ticpty i.cpty)
{
 	 if i.cpty =  ticpty.full then  
		|* full cost price : fixed prices included
 	 	 return(tcyesno.yes)
 	 else  
		|* marginal cost price: only variable prices;
		|* fixed costs not included
 	 	 return(tcyesno.no)
 	 endif  
}
|#CNT.en
:FUNC:END
:TEXT:

:TEXT:END
FUNC160
:MPRF:19
:VERS:B40U
:RELE:c4
:CUST:cont
:TCPAC:ti
:TCMOD:cpr
:TFLNO:110
:FUNC:START
function fill.var.ticpr110.chpr(
		string	i.table(8))
{
	if i.table = "ticpr130" then
		ticpr110.cmth 	= ticpr130.cmth
		ticpr110.kocl	= ticpr130.kocl
		ticpr110.cpch	= ticpr130.cpch
	endif

	|* ticpr110.chpr = surcharge percentage. 
	|* In Baan IV amount and percentage use the same field (ticpr110.cpch)

	if ticpr110.cmth = tccmth.amount then 
		|* percentage := 0
		var.ticpr110.chpr = 0 
	else 
		|* methode = %. 
		if ticpr110.kocl = tckocl.charge then 	
			|* ticpr110.cpch contains %. So also in case of MC,
			|* only the first element is filled. 
			var.ticpr110.chpr = fill.mc.field.double(ticpr110.cpch,1) 
		else
			|* Line type is subtotal or cumulative
			|* set percentage to zero.
			var.ticpr110.chpr = 0 
		endif 
	endif

}

function fill.var.ticpr110.cpch(
		string	i.table(8))
{
	if i.table = "ticpr130" then
		ticpr110.cmth 	= ticpr130.cmth
		ticpr110.kocl	= ticpr130.kocl
		ticpr110.cpch	= ticpr130.cpch
	endif

	|* ticpr110.cpch = surcharge amount
	|* In Baan IV amount and percentage use the same field (ticpr110.cpch)

 	 for element =  1 to 3  
 	 	 if ticpr110.cmth =  tccmth.amount and ticpr110.kocl =  tckocl.charge then  
			|* method is amount and line type = surcharge. 
 	 	 	 var.ticpr110.cpch(element) =  fill.mc.field.double(  
 	 	 	 	 	 ticpr110.cpch,  
 	 	 	 	 	 element,  
 	 	 	 	 	 0.0) 	  
 	 	 else  
			|* percentage or total /cumul line. 
 	 	 	 var.ticpr110.cpch(element) =  0.0  
 	 	 endif  
 	 endfor
}

function fill.var.ticpr110.chcp(
		domain	tccpcp	i.cpcp)
{
	|* ticpr110.chcp = Cost Component

	get.cost.components(bcorig.ticpr, i.cpcp, "", tmp.errmess) 
	var.ticpr110.chcp = bcstc006.cost

}
:FUNC:END
:TEXT:

:TEXT:END
FUNC160
:MPRF:19
:VERS:B40U
:RELE:c4
:CUST:cont
:TCPAC:ti
:TCMOD:cpr
:TFLNO:150
:FUNC:START
|#CNT.sn
function domain tcyesno variable.costs(
			domain tivafi	i.vafi)
{

	 if i.vafi =  tivafi.var then  
 	 	 return(tcyesno.yes)
 	 else  
 	 	 return( tcyesno.no  )
 	 endif  

}

function long set.orty(
		domain	tioprt	i.oprt, 	|* Direct / Overhead
		domain	tccmoh	i.cmoh)	|* Calc. Method
{
	long 	retval


	retval = 0

	on case i.oprt
	case tioprt.wages:
		|* Wages -> labor costs
		retval = 1
		break
	case tioprt.machine:
		|* Machine -> machine costs
		retval = 2
		break
	case tioprt.overhead: |* overhead
		if (i.cmoh =  tccmoh.man.hrs) then  
			| *  Overhead on Man Hours  
 	 		retval = 3 
 	 	else  
			| *  Overhead on Machine Hours  
 	 		 retval =  4 
 	 	endif
		break
	endcase
	return(retval)
}
|#CNT.en
:FUNC:END
:TEXT:

:TEXT:END
FUNC160
:MPRF:19
:VERS:B40U
:RELE:c4
:CUST:cont
:TCPAC:ti
:TCMOD:cpr
:TFLNO:200
:FUNC:START
function get.item.type.group(
			domain	tccprj	i.cprj, 
			domain	tcitem 	i.item,
		ref	domain	tckitm	o.kitm, 
		ref	domain	tccitg	o.citg,
		ref	domain	tccpcp	o.cpcp)

{
	o.citg  = ""
	o.kitm = tckitm.manufacture
	if isspace(i.cprj) then
	 	select 	tiitm001.kitm:o.kitm, 
			tiitm001.citg:o.citg,
			tiitm001.cpcp:o.cpcp
	 	from tiitm001  
 		where tiitm001._index1 =  {:i.item}  
	 	as set with 1 rows  
 		selectdo  
		endselect
	else
	 	select 	tipcs021.kitm:o.kitm, 
			tipcs021.citg:o.citg,
			tipcs021.cpcp:o.cpcp
	 	from tipcs021  
 		where tipcs021._index1 =  {:i.cprj, :i.item}  
	 	as set with 1 rows  
 		selectdo  
		endselect

	endif
}

function get.calc.part.type.group(
			domain	tccbdg	i.cbdg,
			domain	tcitem 	i.ccpc,
		ref	domain	tckitm	o.kitm, 
		ref	domain	tccitg	o.citg, 
		ref	domain	tccpcp	o.cpcp)

{
	o.citg = ""
	o.kitm = tckitm.manufacture

	select	tipcs002.kitm:o.kitm,
		tipcs002.citg:o.citg,
		tipcs002.cpcp:o.cpcp
	from	tipcs002
	where	tipcs002._index1 = {:i.cbdg, :i.ccpc}
	as set with 1 rows
	selectdo
	endselect
}


function fill.var.spit.for.ticpr201(
			domain tccpcc	i.cpcc,
			domain	tcitem	i.item)  

{
	select	ticpr220.cpcc
	from	ticpr220
	where	ticpr220._index1 = {:i.cpcc, :i.item}
	as set with 1 rows
	selectdo	
		var.spit = tcyesno.yes
	selectempty
		var.spit = tcyesno.no
	endselect
}

function  fill.var.spit.for.ticpr301(  
 	 	 domain	tcitem	i.item,  
 	 	 long		i.indt)  

{
	select	ticpr320.indt
	from	ticpr320
	where	ticpr320._index1 = {:i.item, "", :i.indt}
	as set with 1 rows
	selectdo	
		var.spit = tcyesno.yes
	selectempty
		var.spit = tcyesno.no
	endselect

}


function get.aggr.cpcp(
		domain	tckitm	i.kitm, 
		domain	tccitg	i.citg, 
		domain	tccpcp	i.cpcp)  

{
	|*---------------------------------------------------------
	|* this function fill the following global variables
	|* - aggr.mat.cpcp
	|* - aggr.oper.cpcp
	|* - aggr.surch.cpcp
	|* Use data from bcstc010 (Defaults by Item Type /Group)
	|* If these are not filled, then use company settings. 
	|* 
	|* Precondition: bcstc000 has been read
	|*-----------------------------------------------------------

	get.aggr.cost.comp.for.item(	i.kitm,
					i.citg,
					i.cpcp,
					aggr.mat.cpcp,
					aggr.opr.cpcp,
					aggr.sur.cpcp)
}

function  init.aggr.amnts.and.nuni() 
{

	|*------------------------------------------------------------------
	|* this function sets the following global variables to zero
	|* - aggr.mat.amnt / aggr.mat.amnt.var / aggr.mat.amnt.fixed
	|* - aggr.opr.amnt / aggr.opr.amnt.var / aggr.opr.amnt.fixed
	|* - aggr.sur.amnt / aggr.sur.amnt.var / aggr.sur.amnt.fixed
	|* - aggr.mat.nuni
	|* - aggr.opr.nuni
	|* - aggr.sur.nuni
	|*-------------------------------------------------------------------
	long	ret				|#MCR.n

|	aggr.mat.amnt = 0.0			|#MCR.so
|	aggr.opr.amnt = 0.0
|	aggr.sur.amnt = 0.0			|#MCR.eo
	ret =  set.mem(aggr.mat.amnt,0.0,3)	|#MCR.sn
	ret =  set.mem(aggr.opr.amnt,0.0,3)
	ret =  set.mem(aggr.sur.amnt,0.0,3)	|#MCR.en
	
	aggr.mat.amnt.var	= 0.0		|#CNT.sn
	aggr.mat.amnt.fixed	= 0.0	
	aggr.opr.amnt.var	= 0.0		
	aggr.opr.amnt.fixed	= 0.0		
	aggr.sur.amnt.var	= 0.0		
	aggr.sur.amnt.fixed	= 0.0		|#CNT.en

	aggr.mat.nuni = 0.0
	aggr.opr.nuni = 0.0
	aggr.sur.nuni = 0.0

	tmp.max.nr.cpcp.cpr206 = 0
	tmp.max.nr.cpcp.cpr306 = 0
}


function save.max.nr.cpcp()
{
	if tmp.max.nr.cpcp.cpr206 > var.max.nr.cpcp then
		var.max.nr.cpcp = tmp.max.nr.cpcp.cpr206
	endif

	if tmp.max.nr.cpcp.cpr306 > var.max.nr.cpcp then
		var.max.nr.cpcp = tmp.max.nr.cpcp.cpr306
	endif

}

 function  aggr.amount(  	 
		|domain	tccopr	i.amnt, 	|#MCR.o
	ref	domain	tccopr	i.amnt(), 	|#MCR.n
		domain	tccopr	i.amnt.var,	|#CNT.n
		domain	tccopr	i.amnt.fixed,	|#CNT.n
 	   	domain	tcqnu1	i.nuni,  
		domain	tccref	i.cref, 
		domain	tckitm	i.kitm)  

	|*------------------------------------------------------------------
	|* this function aggregates i.amnt and i.nuni into:
	|* - aggr.mat.amnt  / aggr.mat.amnt.var / aggr.mat.amnt.fixed
	|* - aggr.opr.amnt  / aggr.opr.amnt.var / aggr.opr.amnt.fixed
	|* - aggr.sur.amnt / aggr.sur.amnt.var / aggr.sur.amnt.fixed
	|* - aggr.mat.nuni
	|* - aggr.opr.nuni
	|* - aggr.sur.nuni
	|* NB. General Costs are aggregated on Surcharges, 
	|*       except for Cost Items: these are aggr. on Mat. Comp.
	|*-------------------------------------------------------------------
{
	if i.cref = tccref.material or (i.kitm = tckitm.cost) then
		|aggr.mat.amnt = aggr.mat.amnt + i.amnt		|#MCR.o
		aggr.mat.amnt(1) = aggr.mat.amnt(1) + i.amnt(1)	|#MCR.sn
		aggr.mat.amnt(2) = aggr.mat.amnt(2) + i.amnt(2)
		aggr.mat.amnt(3) = aggr.mat.amnt(3) + i.amnt(3)	|#MCR.en

		aggr.mat.amnt.var   = aggr.mat.amnt.var + i.amnt.var		|#CNT.n
		aggr.mat.amnt.fixed = aggr.mat.amnt.fixed + i.amnt.fixed	|#CNT.n

		aggr.mat.nuni = aggr.mat.nuni + i.nuni
		return
	endif

	if i.cref = tccref.operation then
		|aggr.opr.amnt = aggr.opr.amnt + i.amnt		|#MCR.o
		aggr.opr.amnt(1) = aggr.opr.amnt(1) + i.amnt(1)	|#MCR.sn
		aggr.opr.amnt(2) = aggr.opr.amnt(2) + i.amnt(2)
		aggr.opr.amnt(3) = aggr.opr.amnt(3) + i.amnt(3)	|#MCR.en

		aggr.opr.amnt.var   = aggr.opr.amnt.var + i.amnt.var	|#CNT.n
		aggr.opr.amnt.fixed = aggr.opr.amnt.fixed + i.amnt.fixed	|#CNT.n

		aggr.opr.nuni = aggr.opr.nuni + i.nuni
		return
	endif

	if (i.cref = tccref.chg.operation) or 
	    (i.cref = tccref.chg.material) or
	    (i.cref = tccref.general) then
		|aggr.sur.amnt = aggr.sur.amnt + i.amnt		|#MCR.o
		aggr.sur.amnt(1) = aggr.sur.amnt(1) + i.amnt(1)	|#MCR.sn
		aggr.sur.amnt(2) = aggr.sur.amnt(2) + i.amnt(2)
		aggr.sur.amnt(3) = aggr.sur.amnt(3) + i.amnt(3)	|#MCR.en

		aggr.sur.amnt.var   = aggr.sur.amnt.var + i.amnt.var	|#CNT.n
		aggr.sur.amnt.fixed = aggr.sur.amnt.fixed + i.amnt.fixed	|#CNT.n

		aggr.sur.nuni = aggr.sur.nuni + i.nuni
	endif

}

function domain tcbool detailed.cpcp(
		domain	tckitm	i.kitm, 
		domain	tccitg	i.citg,
		domain	tccpcp	i.cpcp)

{
	|*-----------------------------------------------------
	|* If cost component is in the Cost Component Chart,
	|* of the item type/group, then the costs components,
	|* must be tracked in detail.
	|* Otherwise use aggregated cost components.  
	|*
	|* NB. i.cpcp must be Baan IV cost component 
	|* 	(from ticpr010). 
	|* global input:
	|* - var.cpcp
	|*-----------------------------------------------------

	long	ret.val

	if var.cpcp = aggr.mat.cpcp or
	   var.cpcp = aggr.opr.cpcp or
	   var.cpcp = aggr.sur.cpcp then
		|* Aggregated Cost Comp. So, not detaield. 
		return(false)
	endif


	ret.val = get.cost.component.charts.per.item.type.and.group(
		  		 i.kitm, 
				 i.citg, 
				 tmp.errmess)
	if ret.val = 0 then
		|* chart found
		ret.val = get.cost.component.charts.details(
				bcsti007.chrt, 
				i.cpcp,
				tmp.errmess)
		if ret.val = 0 then
			|* cost component found in chart. Detailed Cost Comp!
			return(true)
		endif
	endif
	return(false)
			
}

function dump.1.ticpr200.eff.cpcp()
{	|* Cost Price by Calc. Code, Item, Eff. Cost Comp.
	dump 1
}

function dump.1.ticpr200.aggr.cpcp()
{
	|*-----------------------------------------------------
	|* This function dumps the data into ticpr200
	|* 	Cost Price by Calc. Code, Item, Eff. Cost Comp
	|* 
	|* Global inputs: 
	|* var.item
	|* var.cpcc
	|* aggr.mat.cpcp, aggr.mat.nuni, aggr.mat.amnt
	|*--------------------------------------------------------------

	var.cpcp = aggr.mat.cpcp
	var.nuni = aggr.mat.nuni
	|var.amnt = aggr.mat.amnt			|#MCR.o
	var.amnt(1) = aggr.mat.amnt(1)			|#MCR.sn
	var.amnt(2) = aggr.mat.amnt(2)
	var.amnt(3) = aggr.mat.amnt(3)			|#MCR.en
	
	|if var.nuni <> 0.0 or var.amnt <> 0.0 then	|#MCR.o
|	if var.nuni <> 0.0 or var.amnt(1) <> 0.0 then	|#MCR.n  |#zero.o
		dump 1
|	endif						|#zero.o

	var.cpcp = aggr.opr.cpcp
	var.nuni = aggr.opr.nuni
	|var.amnt = aggr.opr.amnt			|#MCR.o
	var.amnt(1) = aggr.opr.amnt(1)			|#MCR.sn
	var.amnt(2) = aggr.opr.amnt(2)
	var.amnt(3) = aggr.opr.amnt(3)			|#MCR.en







	|if var.nuni <> 0.0 or var.amnt <> 0.0 then	|#MCR.o
|	if var.nuni <> 0.0 or var.amnt(1) <> 0.0 then	|#MCR.n	|#zero.o
		dump 1
|	endif						|#zero.o

	var.cpcp = aggr.sur.cpcp
	var.nuni = aggr.sur.nuni
	|var.amnt = aggr.sur.amnt			|#MCR.o
	var.amnt(1) = aggr.sur.amnt(1)			|#MCR.sn
	var.amnt(2) = aggr.sur.amnt(2)
	var.amnt(3) = aggr.sur.amnt(3)			|#MCR.en
	
	|if var.nuni <> 0.0 or var.amnt <> 0.0 then	|#MCR.o
|	if var.nuni <> 0.0 or var.amnt(1) <> 0.0 then	|#MCR.n	|#zero.o
		dump 1
|	endif						|#zero.o

}

function dump.2.ticpr201()
{
	|* Calc. Code, Item
	dump 2
}

function dump.3.ticpr205.det.cpcp()
{
	|* Cost Price by Calc. Code, Item, Detailed Cost Comp. 
	dump 3
}

function dump.4.ticpr300.eff.cpcp()
{	|* Standard Cost Price Item, Eff. Cost Comp.
	dump 4
}

function dump.4.ticpr300.aggr.cpcp()
{
	|*-----------------------------------------------------
	|* This function dumps the data into ticpr300
	|* 	Standard Cost Price Item, Eff. Cost Comp
	|* 
	|* Global Input:
	|* var.item
	|* aggr.mat.cpcp, aggr.mat.nuni, aggr.mat.amnt
	|*--------------------------------------------------------------

	var.cpcp = aggr.mat.cpcp
	var.nuni = aggr.mat.nuni
	|var.amnt = aggr.mat.amnt			|#MCR.o
	var.amnt(1) = aggr.mat.amnt(1)			|#MCR.sn
	var.amnt(2) = aggr.mat.amnt(2)
	var.amnt(3) = aggr.mat.amnt(3)			|#MCR.en
	|if var.nuni <> 0.0 or var.amnt <> 0.0 then	|#MCR.o
|	if var.nuni <> 0.0 or var.amnt(1) <> 0.0 then	|#MCR.n	|#zero.o
		dump 4
|	endif						|#zero.o

	var.cpcp = aggr.opr.cpcp
	var.nuni = aggr.opr.nuni
	|var.amnt = aggr.opr.amnt			|#MCR.o
	var.amnt(1) = aggr.opr.amnt(1)			|#MCR.sn
	var.amnt(2) = aggr.opr.amnt(2)
	var.amnt(3) = aggr.opr.amnt(3)			|#MCR.en
	|if var.nuni <> 0.0 or var.amnt <> 0.0 then	|#MCR.o
|	if var.nuni <> 0.0 or var.amnt(1) <> 0.0 then	|#MCR.n	|#zero.o
		dump 4
|	endif						|#zero.o

	var.cpcp = aggr.sur.cpcp
	var.nuni = aggr.sur.nuni
	|var.amnt = aggr.sur.amnt			|#MCR.o
	var.amnt(1) = aggr.sur.amnt(1)			|#MCR.sn
	var.amnt(2) = aggr.sur.amnt(2)
	var.amnt(3) = aggr.sur.amnt(3)			|#MCR.en
	|if var.nuni <> 0.0 or var.amnt <> 0.0 then	|#MCR.o
|	if var.nuni <> 0.0 or var.amnt(1) <> 0.0 then	|#MCR.n	|#zero.o
		dump 4
|	endif						|#zero.o

}

function dump.5.ticpr301()
{
	|* Item, Effective Date
	dump 5
}

function dump.6.ticpr305.det.cpcp()
{
	|* Standard Cost Price by Item, Detailed Cost Comp. 
	dump 6
}

function dump.7.ticpr306.aggr.cpcp()
{
	|*--------------------------------------------------------
	|* Effective Standard Cost Price Structure : 
	|* 	Item, indt, cpcp
	|*
	|* Precondition: the following fields are filled:
	|* - var.item
	|*---------------------------------------------------------

	
|	if aggr.mat.nuni <> 0.0 or aggr.mat.amnt(1) <> 0 then	|#zero.o
		var.cpcp = aggr.mat.cpcp
		var.agcp = 2
		dump 7
		tmp.max.nr.cpcp.cpr306 = tmp.max.nr.cpcp.cpr306  + 1

|	endif							|#zero.o

|	if aggr.opr.nuni <> 0.0 or aggr.opr.amnt(1) <> 0 then	|#zero.o
		var.cpcp = aggr.opr.cpcp
		var.agcp = 3
		dump 7
		tmp.max.nr.cpcp.cpr306 = tmp.max.nr.cpcp.cpr306  + 1
|	endif							|#zero.o

|	if aggr.sur.nuni <> 0.0 or aggr.sur.amnt(1) <> 0 then	|#zero.o
		var.cpcp = aggr.sur.cpcp
		var.agcp = 5 
		tmp.max.nr.cpcp.cpr306 = tmp.max.nr.cpcp.cpr306  + 1
		dump 7
|	endif							|#zero.o

	save.max.nr.cpcp()
}

function dump.7.ticpr306.eff.cpcp()
{
	|*--------------------------------------------------------
	|* Effective Cost Price Structure : 
	|* The non-aggragated cpcp's that must be
	|* tracked in detail. 
	|*
	|* Precondition: the following fields are filled:
	|* - var.item
	|* - var.cpcp
	|*---------------------------------------------------------

	|* do not insert a record if Cost Component is
	|* known as aggregated cost component. 
	if var.cpcp = aggr.mat.cpcp or 
	   var.cpcp = aggr.opr.cpcp or 
	  var.cpcp = aggr.sur.cpcp then
		return
	endif
	

	var.agcp = 1
	dump 7

	tmp.max.nr.cpcp.cpr306 = tmp.max.nr.cpcp.cpr306  + 1
	save.max.nr.cpcp()

}

function dump.8.ticpr206.aggr.cpcp()
{	
	|*--------------------------------------------------------
	|* Cost Price Structure : 
	|* 	Item, cpcp
	|*
	|* Precondition: the following fields are filled:
	|* - var.item
	|*---------------------------------------------------------

|	if aggr.mat.nuni <> 0.0 or aggr.mat.amnt(1) <> 0 then		|#zero.o
		var.cpcp = aggr.mat.cpcp
		var.agcp = 2
		dump 8
		tmp.max.nr.cpcp.cpr206 = tmp.max.nr.cpcp.cpr206 + 1
|	endif								|#zero.o
	
|	if aggr.opr.nuni <> 0.0 or aggr.opr.amnt(1) <> 0 then		|#zero.o
		var.cpcp = aggr.opr.cpcp
		var.agcp = 3
		dump 8
		tmp.max.nr.cpcp.cpr206 = tmp.max.nr.cpcp.cpr206 + 1
|	endif								|#zero.o
	
|	if aggr.sur.nuni <> 0.0 or aggr.sur.amnt(1) <> 0 then		|#zero.o
		var.cpcp = aggr.sur.cpcp
		var.agcp = 5 
		dump 8
		tmp.max.nr.cpcp.cpr206 = tmp.max.nr.cpcp.cpr206 + 1
|	endif								|#zero.o

	save.max.nr.cpcp()

}

function dump.8.ticpr206.eff.cpcp()
{
	|*--------------------------------------------------------
	|* Cost Price Structure : 
	|* The non-aggragated cpcp's that must be
	|* tracked in detail. 
	|*
	|* Precondition: the following fields are filled:
	|* - var.item
	|* - var.cpcp
	|*---------------------------------------------------------


	|* do not insert a record if Cost Component is
	|* known as aggregated cost component. 
	if var.cpcp = aggr.mat.cpcp or 
	   var.cpcp = aggr.opr.cpcp or 
	  var.cpcp = aggr.sur.cpcp then
		return
	endif
	
	var.agcp = 1
	dump 8
	
	tmp.max.nr.cpcp.cpr206 = tmp.max.nr.cpcp.cpr206 + 1
	save.max.nr.cpcp()

}

function dump.9.ticpr240.aggr.cpcp()
{
	|*-----------------------------------------------------
	|* This function dumps the data into ticpr240
	|* 	Item Valuation Price (by Calc. Code, 
	|* 		on Cost Comp. Struct.)
	|* 
	|* Global inputs: 
	|* var.item
	|* var.cpcc
	|* aggr.mat.cpcp, aggr.mat.nuni, aggr.mat.amnt
	|*--------------------------------------------------------------

	|*------------------------------
	|* Material costs
	|*------------------------------
	var.cpcp = aggr.mat.cpcp
	var.nuni = aggr.mat.nuni
|#CNT.sn
	|* Fixed costs are included in cost price, depening on ticpr / tipcs parameter
	|* "include fixed costs". 
	if var.cpty = ticpty.full then
		var.ticpr240.amnt = aggr.mat.amnt(1)
	else
		var.ticpr240.amnt = aggr.mat.amnt.var
	endif
	var.amnt.var 	= aggr.mat.amnt.var
	var.amnt.fixed	= aggr.mat.amnt.fixed
	dump 9
|#CNT.en
|#CNT.so
|	|var.amnt = aggr.mat.amnt			|#MCR.o
|	var.amnt(1) = aggr.mat.amnt(1)			|#MCR.sn
|	var.amnt(2) = aggr.mat.amnt(2)
|	var.amnt(3) = aggr.mat.amnt(3)			|#MCR.en
|	|if var.nuni <> 0.0 or var.amnt <> 0.0 then	|#MCR.o
||	if var.nuni <> 0.0 or var.amnt(1) <> 0.0 then	|#MCR.n|#zero.o
|		dump 9
||	endif						|#zero.o
|#CNT.eo


	|*------------------------------
	|* Operation costs
	|*------------------------------
	var.cpcp = aggr.opr.cpcp
	var.nuni = aggr.opr.nuni
|#CNT.sn
	|* Fixed costs are included in cost price, depening on ticpr / tipcs parameter
	|* "include fixed costs". 
	if var.cpty = ticpty.full then
		var.ticpr240.amnt = aggr.opr.amnt(1)
	else
		var.ticpr240.amnt = aggr.opr.amnt.var
	endif
	var.amnt.var 	= aggr.opr.amnt.var
	var.amnt.fixed	= aggr.opr.amnt.fixed
	dump 9
|#CNT.en
|#CNT.so
|	|var.amnt = aggr.opr.amnt			|#MCR.o
|	var.amnt(1) = aggr.opr.amnt(1)			|#MCR.sn
|	var.amnt(2) = aggr.opr.amnt(2)
|	var.amnt(3) = aggr.opr.amnt(3)			|#MCR.en
|	|if var.nuni <> 0.0 or var.amnt <> 0.0 then	|#MCR.o
||	if var.nuni <> 0.0 or var.amnt(1) <> 0.0 then	|#MCR.n	|#zero.o
|		dump 9
|	endif						|#zero.o
|#CNT.eo

	|*------------------------------
	|* Surcharge costs
	|*------------------------------
	var.cpcp = aggr.sur.cpcp
	var.nuni = aggr.sur.nuni
|#CNT.sn
	|* Fixed costs are included in cost price, depening on ticpr / tipcs parameter
	|* "include fixed costs". 
	if var.cpty = ticpty.full then
		var.ticpr240.amnt = aggr.sur.amnt(1)
	else
		var.ticpr240.amnt = aggr.sur.amnt.var
	endif
	var.amnt.var 	= aggr.sur.amnt.var
	var.amnt.fixed	= aggr.sur.amnt.fixed
	dump 9
|#CNT.en
|#CNT.so
|	|var.amnt = aggr.sur.amnt			|#MCR.o
|	var.amnt(1) = aggr.sur.amnt(1)			|#MCR.sn
|	var.amnt(2) = aggr.sur.amnt(2)
|	var.amnt(3) = aggr.sur.amnt(3)			|#MCR.en
|	|if var.nuni <> 0.0 or var.amnt <> 0.0 then	|#MCR.o
||	if var.nuni <> 0.0 or var.amnt(1) <> 0.0 then	|#MCR.n	|#zero.o
|		dump 9
|	endif						|#zero.o
|#CNT.eo

}

function dump.9.ticpr240.eff.cpcp()
{

	|*-----------------------------------------------------
	|* This function dumps the Cost Components
	|*  that must be tracked in detail, into ticpr240
	|* 	Item Valuation Price (by Calc. Code, 
	|* 		on Cost Comp. Struct.)
	|* 
	|* Global inputs: 
	|* var.item
	|* var.cpcc
	|* var.cpcp
	|*-------------------------------------------------------------

|#CNT.sn
	|* Fixed costs are included in cost price, depening on ticpr / tipcs parameter
	|* "include fixed costs". 
	if var.cpty = ticpty.full then
		var.ticpr240.amnt = var.amnt(1)
	else
		var.ticpr240.amnt = var.amnt.var
	endif
|#CNT.en

	dump 9
}


function dump.10.ticpr340.aggr.cpcp()
{
	|*-----------------------------------------------------
	|* This function dumps the data into ticpr340
	|* 	Item Standard Valuation Price ( 
	|* 		on Cost Comp. Struct.)
	|* 
	|* Global inputs: 
	|* var.item
	|* aggr.mat.cpcp, aggr.mat.nuni, aggr.mat.amnt
	|*--------------------------------------------------------------

	|*------------------------------
	|* Material costs
	|*------------------------------
	var.cpcp = aggr.mat.cpcp
	var.nuni = aggr.mat.nuni
|#CNT.sn
	|* Fixed costs are included in cost price, depening on ticpr / tipcs parameter
	|* "include fixed costs". 
	if var.cpty = ticpty.full then
		var.ticpr340.amnt = aggr.mat.amnt(1)
	else
		var.ticpr340.amnt = aggr.mat.amnt.var
	endif
	var.amnt.var 	= aggr.mat.amnt.var
	var.amnt.fixed	= aggr.mat.amnt.fixed
	dump 10
|#CNT.en
|#CNT.so
|	|var.amnt = aggr.mat.amnt			|#MCR.o
|	var.amnt(1) = aggr.mat.amnt(1)			|#MCR.sn
|	var.amnt(2) = aggr.mat.amnt(2)
|	var.amnt(3) = aggr.mat.amnt(3)			|#MCR.en
|	|if var.nuni <> 0.0 or var.amnt <> 0.0 then	|#MCR.o
||	if var.nuni <> 0.0 or var.amnt(1) <> 0.0 then	|#MCR.n	|#zero.o
|		dump 10
||	endif						|#zero.o
|#CNT.so


	|*------------------------------
	|* Operation costs
	|*------------------------------
	var.cpcp = aggr.opr.cpcp
	var.nuni = aggr.opr.nuni
|#CNT.sn
	|* Fixed costs are included in cost price, depening on ticpr / tipcs parameter
	|* "include fixed costs". 
	if var.cpty = ticpty.full then
		var.ticpr340.amnt = aggr.opr.amnt(1)
	else
		var.ticpr340.amnt = aggr.opr.amnt.var
	endif
	var.amnt.var 	= aggr.opr.amnt.var
	var.amnt.fixed	= aggr.opr.amnt.fixed
	dump 10
|#CNT.en
|#CNT.so
|	|var.amnt = aggr.opr.amnt			|#MCR.o
|	var.amnt(1) = aggr.opr.amnt(1)			|#MCR.sn
|	var.amnt(2) = aggr.opr.amnt(2)
|	var.amnt(3) = aggr.opr.amnt(3)			|#MCR.en
|	|if var.nuni <> 0.0 or var.amnt <> 0.0 then	|#MCR.o
||	if var.nuni <> 0.0 or var.amnt(1) <> 0.0 then	|#MCR.n	|#zero.o
|		dump 10	
||	endif						|#zero.o
|#CNT.eo


	|*------------------------------
	|* Surcharge costs
	|*------------------------------
	var.cpcp = aggr.sur.cpcp
	var.nuni = aggr.sur.nuni
|#CNT.sn
	|* Fixed costs are included in cost price, depening on ticpr / tipcs parameter
	|* "include fixed costs". 
	if var.cpty = ticpty.full then
		var.ticpr340.amnt = aggr.sur.amnt(1)
	else
		var.ticpr340.amnt = aggr.sur.amnt.var
	endif
	var.amnt.var 	= aggr.sur.amnt.var
	var.amnt.fixed	= aggr.sur.amnt.fixed
	dump 10
|#CNT.en
|#CNT.so
|	|var.amnt = aggr.sur.amnt			|#MCR.o
|	var.amnt(1) = aggr.sur.amnt(1)			|#MCR.sn
|	var.amnt(2) = aggr.sur.amnt(2)
|	var.amnt(3) = aggr.sur.amnt(3)			|#MCR.en
|	|if var.nuni <> 0.0 or var.amnt <> 0.0 then	|#MCR.o
||	if var.nuni <> 0.0 or var.amnt(1) <> 0.0 then	|#MCR.n	|#zero.o
|		dump 10
||	endif						|#zero.o
|#CNT.eo	

}

function dump.10.ticpr340.eff.cpcp()
{

	|*-----------------------------------------------------
	|* This function dumps the Cost Components

	|*  that must be tracked in detail, into ticpr340
	|* 	Item Standard Valuation Price (
	|* 		on Cost Comp. Struct.)
	|* 
	|* Global inputs: 
	|* var.item
	|* var.amnt
	|* var.nuni
	|* var.cpcp
	|*-------------------------------------------------------------
|#CNT.sn
	|* Fixed costs are included in cost price, depening on ticpr / tipcs parameter
	|* "include fixed costs". 

	if var.cpty = ticpty.full then
		var.ticpr340.amnt = var.amnt(1)
	else
		var.ticpr340.amnt = var.amnt.var
	endif
|#CNT.en
|
	dump 10
}

function dump.11.ticpr099()
{
	|* This function fills ticpr099. It has one record and contains
	|* the maximum size of the Cost Component Structure

	dump 11

}
:FUNC:END
:TEXT:

:TEXT:END
FUNC160
:MPRF:19
:VERS:B40U
:RELE:c4
:CUST:cont
:TCPAC:ti
:TCMOD:cpr
:TFLNO:220
:FUNC:START
function domain tcyesno variable.costs(
			domain tivafi	i.vafi)
{

	 if i.vafi =  tivafi.var then  
 	 	 return(tcyesno.yes)
 	 else  
 	 	 return( tcyesno.no  )
 	 endif  

}
:FUNC:END
:TEXT:

:TEXT:END
FUNC160
:MPRF:19
:VERS:B40U
:RELE:c4
:CUST:cont
:TCPAC:ti
:TCMOD:cpr
:TFLNO:320
:FUNC:START
function domain tcyesno variable.costs(
			domain tivafi	i.vafi)
{

	 if i.vafi =  tivafi.var then  
 	 	 return(tcyesno.yes)
 	 else  
 	 	 return( tcyesno.no  )
 	 endif  

}
:FUNC:END
:TEXT:

:TEXT:END
FUNC160
:MPRF:19
:VERS:B40U
:RELE:c4
:CUST:cont
:TCPAC:ti
:TCMOD:pcs
:TFLNO:000
:FUNC:START
function domain tcyesno include.fixed.costs(
			domain	ticpty i.cpty)
{
 	 if i.cpty =  ticpty.full then  
		|* full cost price : fixed prices included
 	 	 return(tcyesno.yes)
 	 else  
		|* marginal cost price: only variable prices;
		|* fixed costs not included
 	 	 return(tcyesno.no)
 	 endif  
}
:FUNC:END
:TEXT:

:TEXT:END
FUNC160
:MPRF:19
:VERS:B40U
:RELE:c4
:CUST:cont
:TCPAC:ti
:TCMOD:pcs
:TFLNO:320
:FUNC:START
function domain tcyesno variable.costs(
			domain tivafi	i.vafi)
{

	 if i.vafi =  tivafi.var then  
 	 	 return(tcyesno.yes)
 	 else  
 	 	 return( tcyesno.no  )
 	 endif  

}
:FUNC:END
:TEXT:

:TEXT:END
FUNC160
:MPRF:19
:VERS:B40U
:RELE:c4
:CUST:cont
:TCPAC:wh
:TCMOD:inr
:TFLNO:110
:FUNC:START
function domain tcpono determine.rpl.order.sequence(	domain	tcorno	i.orno,
							domain	tcpono	i.pono,
							domain	tckost	i.kost,
							domain	tccwar	i.cwar,
							domain	tcdate	i.trdt)
{
	if i.kost = tckost.rpl.delivery then
		select	tdrpl100.srnb
		from	tdrpl100
		where	tdrpl100._index1 = {:i.orno, :i.pono}
		and	tdrpl100.rwar = :i.cwar
		and	tdrpl100.rddt = :i.trdt
		as set with 1 rows
		selectdo
			 return(tdrpl100.srnb)
		endselect
	else
		select	tdrpl100.srnb
		from	tdrpl100
		where	tdrpl100._index1 = {:i.orno, :i.pono}
		and	tdrpl100.dwar = :i.cwar
		and	tdrpl100.rrdt = :i.trdt
		as set with 1 rows
		selectdo
			 return(tdrpl100.srnb)
		endselect
	endif
	return(0)
}

function domain tcpono determine.sales.order.sequence(	domain	tcbool	i.inv,	|#800-143063.n
							domain	tcorno	i.orno,
							domain	tcpono	i.pono,
							domain	tcdate	i.trdt,
							domain	tctime	i.time,	|#800-143063.n
							domain	tcsern	i.sern,	|#800-143063.n
							domain	tccprj	i.cprj,	|#800-143063.n
							domain	tcqiv1	i.quan)	|#800-143063.n
{
										|#800-143063.sn
	domain	tcqiv1	already.handled
	domain	tcqiv1	delivered

	already.handled = 0.0
	delivered = 0.0

	if i.inv then
		select	sum(tdinv700.quan):already.handled
		from	tdinv700
		where	tdinv700._index2 ={tckoor.act.sls, :i.orno, :i.pono, :i.trdt}
		and	(tdinv700.trtm < :i.time or (tdinv700.trtm = :i.time and tdinv700.sern < :i.sern))
		selectdo
		endselect
	else
		select	sum(tipcs700.quan):already.handled
		from	tipcs700
		where	tipcs700._index2 ={:i.cprj, tckoor.act.sls, :i.orno, :i.pono, :i.trdt}
		and	(tipcs700.trtm < :i.time or (tipcs700.trtm = :i.time and tipcs700.sern < :i.sern))
		selectdo
		endselect
	endif
										|#800-143063.en

	select	tdsls045.srnb,tdsls045.ddat, tdsls045.dqua
	from	tdsls045
	where	tdsls045._index1 = {:i.orno, :i.pono}
	and	tdsls045.ddat >= :i.trdt
	order by tdsls045.ddat asc
|	as set with 1 rows							|#800-143063.o
	selectdo
		delivered = delivered + tdsls045.dqua				|#800-143063.n
		if delivered >= already.handled + i.quan then			|#800-143063.n
			return(get.sls.order.line.sequence.number(   	 i.orno,  
 	 	 	 	 		 	 		 i.pono,  
 	 	 	 	 		 	 		 tdsls045.srnb))
		endif								|#800-143063.n
	endselect

	return(0)
}

function get.standard.cost.price(domain	tcitem	i.item,
				domain	tcqiv1	i.quan,
				domain	tcdate	i.date,
				domain	tcbool	i.receipt,

				domain	tcbool	i.negative)
{
	long	first.record
	long	result
	long	i, j
	long	counter

	domain	tcdate		hold.date
	static	domain	tcdate		next.date
	static	domain	tcitem		hold.item

	static	domain	bccost		material.component
	static	domain	bccost		operation.component
	static	domain	bccost		surcharge.component
	static	domain tcamnt		material.component.amnt(3)
	static	domain tcamnt		operation.component.amnt(3)
	static	domain tcamnt		surcharge.component.amnt(3)
		domain tcamnt		hold.amnt(3)

	static	domain	bccost		arr.cpcp(1)		based
	static	double			arr.cpcp.amnt(1,1)	based

	static	domain	tcbool	allocated

	domain	bccost		detail.cost.component

	first.record = true

	if not allocated then
		allocated = true
		alloc.mem(arr.cpcp, 8, 20)
		alloc.mem(arr.cpcp.amnt, 20, 3)
	endif

|if i.date >= next.date or hold.item <> i.item then
if hold.item <> i.item then
	set.mem(arr.cpcp,"")
	set.mem(arr.cpcp.amnt, 0.0)

	counter = 0
	hold.item = i.item

 	  set.mem(material.component.amnt, 0.0)  
 	  set.mem(operation.component.amnt, 0.0)
 	  set.mem(surcharge.component.amnt, 0.0)


|	select ticpr300.cpcp, ticpr300.amnt, ticpr300.indt  			|#CNT.o
	select	ticpr300.*							|#CNT.n
 	  from  	  ticpr300  
 	  where ticpr300._index1 =  {:i.item}  
	and	ticpr300.cntr = ""
| 	  and  	  ticpr300.indt <= :i.date  
	and	ticpr300.indt = :tiitm001.ltcp
|	order by ticpr300.indt desc
 	  selectdo  
		if first.record then
			hold.date = ticpr300.indt
			first.record = false
		else
			if hold.date <> ticpr300.indt then
				break
			endif
		endif

  	 	 for i =  1 to g.mc.depth  
|  	 	 	 hold.amnt(i) =  fill.mc.field.double(ticpr300.amnt, i)  |#CNT.o
  	 	 	 hold.amnt(i) =  get.amount.per.cost.component(
							"ticpr300", i)  	|#CNT.n
  	 	 endfor  

 	   	  analyze.cost.component( i.item,  
 	   	   	   	   	  "",  
 	   	   	   	   	  ticpr300.cpcp,  
 	   	   	   	   	  detail.cost.component,  
 	   	   	   	   	  material.component,  
 	   	   	   	   	  operation.component,  
 	   	   	   	   	  surcharge.component,  
 	   	   	   	   	  result)  
 	   	  on case result  
 	   	  case 0:  
 	   	   	   |  *  Cost Component in chart  
 
 	   	   	   |  *  Detail Cost Component  
 			counter = counter + 1
			arr.cpcp(1,counter) = detail.cost.component
  	 		 for i =  1 to g.mc.depth  
				arr.cpcp.amnt(counter,i) = hold.amnt(i)
			endfor
			if i.receipt then
 	   	   		  var.whina113.cpcp =  detail.cost.component  
		  	 	 for i =  1 to g.mc.depth  
	 	   	   		  var.whina113.amnt(i) =  hold.amnt(i) * i.quan
					  var.whina113.mauc(i) = hold.amnt(i)
				endfor	   
 	   	   		  dump 7  |  *  whina113  
			else
 	   	   		  var.whina115.cpcp =  detail.cost.component  
  	 			 for i =  1 to g.mc.depth  
 	   	   		  	var.whina115.amnt(i) =  hold.amnt(i) * i.quan
				endfor
				if i.negative then
					dump 12	|* whina121
				else
 	   	   		  	dump 8  |  *  whina115  
				endif
			endif
 
 	   	   	  break  
 	   	  case 1:  
 	   	   	   |  *  Merge to aggregated material cost component  
 
  	 		 for i =  1 to g.mc.depth  
 	   	   	  	material.component.amnt(i) =   
 	   	   	   	  material.component.amnt(i) + hold.amnt(i) 
			endfor
 	   	   	  break  
 	   	  case 2:  
 	   	   	   |  *  Merge to aggregated operation cost component  
 
  	 		 for i =  1 to g.mc.depth  
 	   		   	  operation.component.amnt(i) =   
 	   	   	   	  operation.component.amnt(i) + hold.amnt(i) 
			endfor
 	   	   	  break  
 	   	  case 3:  
 	   	   	   |  *  Merge to aggregated surcharge cost component  
 
  	 		 for i =  1 to g.mc.depth  
 	   		   	  surcharge.component.amnt(i) =   
 	   	   	   	  surcharge.component.amnt(i) + hold.amnt(i) 
			endfor
 	   	   	  break  
 	   	  endcase 
	selectempty
 	   	  analyze.cost.component( i.item,  
 	   	   	   	   	  "",  
 	   	   	   	   	  "",  
 	   	   	   	   	  detail.cost.component,  
 	   	   	   	   	  material.component,  
 	   	   	   	   	  operation.component,  
 	   	   	   	   	  surcharge.component,  
 	   	   	   	   	  result)  
 	  endselect  

	select ticpr300.indt  
 	  from  	  ticpr300  
 	  where ticpr300._index1 =  {:i.item}  
	and	ticpr300.cntr = ""
 	  and  	  ticpr300.indt > :i.date  
	order by ticpr300.indt 
	as set with 1 rows
 	  selectdo  
		next.date = ticpr300.indt
	selectempty
		set.max(next.date)
	endselect

else
	j = 1
 	while strip$(arr.cpcp(1,j)) <> ""
		if i.receipt then
	  	  	 var.whina113.cpcp =  arr.cpcp(1,j)  
  	 	 	for i =  1 to g.mc.depth  
 	 	  	 	 var.whina113.amnt(i) =  arr.cpcp.amnt(j,i) * i.quan
	  	  		 var.whina113.mauc(i) = arr.cpcp.amnt(j,i)	
			endfor   
 	  		   dump 7  |  *  whina113  
		else
	  		   var.whina115.cpcp =  arr.cpcp(1,j)  
  	 		 for i =  1 to g.mc.depth  
 	 	    		var.whina115.amnt(i) =  arr.cpcp.amnt(j,i) * i.quan
			endfor
			if i.negative then

				dump 12	|* whina121
			else
   			  	dump 8  	|  *  whina115  
			endif

		endif
	     j = j + 1
	endwhile 	   	   
endif
 	   |  *  Material Cost Component  
 
	if i.receipt then
	 	  var.whina113.cpcp =  material.component  
  	 	 for i =  1 to g.mc.depth  
 			  var.whina113.amnt(i) =  material.component.amnt(i) * i.quan
			  var.whina113.mauc(i) = material.component.amnt(i)
		endfor
		dump 7

 		  var.whina113.cpcp =  operation.component  
  	 	 for i =  1 to g.mc.depth  
	 		  var.whina113.amnt(i) =  operation.component.amnt(i) * i.quan
	 		  var.whina113.mauc(i) =  operation.component.amnt(i)
		endfor
		dump 7

	 	  var.whina113.cpcp =  surcharge.component  
  	 	 for i =  1 to g.mc.depth  
	 		  var.whina113.amnt(i) =  surcharge.component.amnt(i) * i.quan
	 		  var.whina113.mauc(i) =  surcharge.component.amnt(i)
		endfor
		dump 7
	else
	 	  var.whina115.cpcp =  material.component  
  	 	 for i =  1 to g.mc.depth  
 		  	var.whina115.amnt(i) =  material.component.amnt(i) * i.quan
		endfor
		if i.negative then
			dump 12	|* whina121
		else
   		  	dump 8  	|  *  whina115  
		endif

 		  var.whina115.cpcp =  operation.component  
  	 	 for i =  1 to g.mc.depth  
	 	 	 var.whina115.amnt(i) =  operation.component.amnt(i) * i.quan
		endfor
		if i.negative then
			dump 12	|* whina121
		else
   		  	dump 8  	|  *  whina115  
		endif

	 	  var.whina115.cpcp =  surcharge.component  
  	 	 for i =  1 to g.mc.depth  
	 	 	 var.whina115.amnt(i) =  surcharge.component.amnt(i) * i.quan
		endfor

		if i.negative then
			dump 12		|* whina121
		else
   		  	dump 8  	|  *  whina115  
		endif
	endif

}

function get.customized.cost.price(	domain	tccprj	i.cprj,
					domain	tcitem	i.item,
					domain	tcqiv1	i.quan,
					domain	tcbool	i.receipt)
{
	long	result
	long	i, j
	long	counter

	static	domain	tccprj		hold.cprj
	static	domain	tcitem		hold.item

	static	domain	bccost		material.component
	static	domain	bccost		operation.component
	static	domain	bccost		surcharge.component
	static	domain tcamnt		material.component.amnt(3)
	static	domain tcamnt		operation.component.amnt(3)
	static	domain tcamnt		surcharge.component.amnt(3)
		domain tcamnt		hold.amte(3)

	domain	bccost			detail.cost.component


	static	domain	bccost		arr.cpcp(1)		based
	static	double			arr.cpcp.amnt(1,1)	based

	static	domain	tcbool	allocated

	if not allocated then
		allocated = true
		alloc.mem(arr.cpcp, 8, 20)
		alloc.mem(arr.cpcp.amnt, 20, 3)
	endif

if hold.item <> i.item or
  hold.cprj <> i.cprj   then
	set.mem(arr.cpcp,"")
	set.mem(arr.cpcp.amnt, 0.0)

	counter = 0
	hold.item = i.item
	hold.cprj = i.cprj

 	  set.mem(material.component.amnt,  0.0)  
 	  set.mem(operation.component.amnt, 0.0)  
 	  set.mem(surcharge.component.amnt, 0.0)  

|	select tipcs350.cpcp, tipcs350.amte 				|#CNT.o
	select	tipcs350.*						|#CNT.n
 	  from  	  tipcs350
 	  where tipcs350._index1 =  {:i.cprj, :i.item}  
 	  selectdo  

  	 	 for i =  1 to g.mc.depth  
|  	 	 	 hold.amte(i) =  fill.mc.field.double(tipcs350.amte, i) |#CNT.o
  	 	 	 hold.amte(i) =  get.amount.per.cost.component(
							"tipcs350", i)  	|#CNT.n
  	 	 endfor  

 	   	  analyze.cost.component( i.item,  
 	   	   	   	   	  i.cprj,  
 	   	   	   	   	  tipcs350.cpcp,  
 	   	   	   	   	  detail.cost.component,  
 	   	   	   	   	  material.component,  
 	   	   	   	   	  operation.component,  
 	   	   	   	   	  surcharge.component,  
 	   	   	   	   	  result)  
 	   	  on case result  
 	   	  case 0:  
 	   	   	   |  *  Cost Component in chart  
 
 	   	   	   |  *  Detail Cost Component  

  			counter = counter + 1
			arr.cpcp(1,counter) = detail.cost.component
  	 		 for i =  1 to g.mc.depth  
				arr.cpcp.amnt(counter,i) = hold.amte(i)
			endfor
			if i.receipt then
 	   		   	  var.whina113.cpcp =  detail.cost.component  
  	 			 for i =  1 to g.mc.depth  
 	   		   	  	var.whina113.amnt(i) =  hold.amte(i) * i.quan
				  	var.whina113.mauc(i) = hold.amte(i)
				endfor	   
 	   		   	  dump 9  |  *  whina113 
			else
 	   		   	  var.whina115.cpcp =  detail.cost.component  
   	 			 for i =  1 to g.mc.depth  
	   		   	 	 var.whina115.amnt(i) =  hold.amte(i) * i.quan
				endfor
 	   		   	  dump 10  |  *  whina115 
			endif 
 
 	   	   	  break  
 	   	  case 1:  
 	   	   	   |  *  Merge to aggregated material cost component  
 
  	 		 for i =  1 to g.mc.depth  
 	   	   		  material.component.amnt(i) =   
 	   	   	   	  material.component.amnt(i) + hold.amte(i)
			endfor 
 	   	   	  break  
 	   	  case 2:  
 	   	   	   |  *  Merge to aggregated operation cost component  
 
  	 		 for i =  1 to g.mc.depth  
 	   	   	  	operation.component.amnt(i) =   
 	   	   	   	  operation.component.amnt(i) + hold.amte(i)
			endfor 
 	   	   	  break  
 	   	  case 3:  
 	   	   	   |  *  Merge to aggregated surcharge cost component  
 
  	 		 for i =  1 to g.mc.depth  
 	   	   		  surcharge.component.amnt(i) =   
 	   	   	   	  surcharge.component.amnt(i) + hold.amte(i)
			endfor 
 	   	   	  break  
 	   	  endcase  
	selectempty
 	   	  analyze.cost.component( i.item,  
 	   	   	   	   	  i.cprj,  
 	   	   	   	   	  "",  
 	   	   	   	   	  detail.cost.component,  
 	   	   	   	   	  material.component,  
 	   	   	   	   	  operation.component,  
 	   	   	   	   	  surcharge.component,  
 	   	   	   	   	  result)  
 	  endselect  

else
	j = 1
 	while strip$(arr.cpcp(1,j)) <> ""
		if i.receipt then
		     var.whina113.cpcp =  arr.cpcp(1,j)  
  	 		 for i =  1 to g.mc.depth  
 		     		var.whina113.amnt(i) =  arr.cpcp.amnt(j,i) * i.quan
		     		var.whina113.mauc(i) = arr.cpcp.amnt(j,i)

			endfor	   
 		     dump 9  |  *  whina113 
		else 
		     var.whina115.cpcp =  arr.cpcp(1,j)  
  	 	 	for i =  1 to g.mc.depth  
 		     		var.whina115.amnt(i) =  arr.cpcp.amnt(j,i) * i.quan
			endfor
 		     dump 10  |  *  whina115 
		endif
	     j = j + 1
	endwhile 	   	   
endif
   	   
 	   |  *  Material Cost Component  
 
	if i.receipt then
	 	  var.whina113.cpcp =  material.component  
  	 	 for i =  1 to g.mc.depth  
	 	  	var.whina113.amnt(i) =  material.component.amnt(i) * i.quan
		  	var.whina113.mauc(i) = material.component.amnt(i)
		endfor
		dump 9

 		  var.whina113.cpcp =  operation.component  
  	 	 for i =  1 to g.mc.depth  
	 		  var.whina113.amnt(i) =  operation.component.amnt(i) * i.quan
 			  var.whina113.mauc(i) =  operation.component.amnt(i)
		endfor
		dump 9

 		  var.whina113.cpcp =  surcharge.component  
  	 	 for i =  1 to g.mc.depth  
 		 	 var.whina113.amnt(i) =  surcharge.component.amnt(i) * i.quan
 			  var.whina113.mauc(i) =  surcharge.component.amnt(i)
		endfor
		dump 9
	else
	 	  var.whina115.cpcp =  material.component  
  	 	 for i =  1 to g.mc.depth  
	 	  	var.whina115.amnt(i) =  material.component.amnt(i) * i.quan
		endfor
		dump 10

 		  var.whina115.cpcp =  operation.component  
  	 	 for i =  1 to g.mc.depth  
 			  var.whina115.amnt(i) =  operation.component.amnt(i) * i.quan
		endfor
 		dump 10

 		  var.whina115.cpcp =  surcharge.component  
  	 	 for i =  1 to g.mc.depth  
 		 	 var.whina115.amnt(i) =  surcharge.component.amnt(i) * i.quan
		endfor
		dump 10
	endif

}

function get.lot.price()
{
}

function domain tcpono determine.new.pono( domain tcorno i.orno)
{
	domain tcpono new.position 

	new.position = tdinv700.pono

	select tdinv100.* 
	from tdinv100 
	where tdinv100._index2 = {:i.orno} 
	as set with 1 rows 
	selectdo 
		select tdilc102.serb 
		from tdilc102 
		where tdilc102._index1 = { 	:tdinv100.cprj, 
						:tdinv100.item, 
						:tdinv100.cntr, 
						:tdinv100.cwar, 
						:tdinv100.idat, 
						:tdinv100.sern} 
		order by tdilc102.serb desc 
		as set with 1 rows 
		selectdo 
			new.position = tdilc102.serb
		selectempty
			new.position = tdinv100.sern
		endselect 
	endselect 
	
	return(new.position)
}

function domain tcbool receipt.transaction(
			domain	tckost	i.transaction.type,
			domain	tcqiv1	i.quantity)
{
 	if (i.transaction.type =  tckost.stc.correction and i.quantity >  0) or  
 	   ((i.transaction.type =  tckost.pur.receipt or  
 	     i.transaction.type =  tckost.prd.receipt or  
 	     i.transaction.type =  tckost.rpl.receipt) and i.quantity >  0) or  
 	   ((i.transaction.type =  tckost.sls.delivery or  
 	      i.transaction.type =  tckost.prd.mat.issue or  
 	      i.transaction.type =  tckost.rpl.delivery) and i.quantity <  0) or  
 	   (i.transaction.type =  tckost.stc.transfer and i.quantity >  0) then  
		return(true)
	else
		return(false)
	endif
}
:FUNC:END
:TEXT:

:TEXT:END
FUNC160
:MPRF:19
:VERS:B40U
:RELE:c4
:CUST:cont
:TCPAC:wh
:TCMOD:ltc
:TFLNO:100
:FUNC:START
function domain tcbool serial.on.other.location()
{
	domain	tdltc.clot	lot.code

 	 select 	tdilc101.clot:lot.code   
 	 from 	tdilc101  
 	 where 	tdilc101._index3 =  {	:tdilc101.cprj,  
 	  	 	 	 	:tdilc101.item,  
 	  	 	 	 	:tdilc101.cntr,  
 	  	 	 	 	:tdilc101.clot,
					:tdilc101.date,
					:tdilc101.stun,
					:tdilc101.cwar}
	and	tdilc101.loca <> :tdilc101.loca  
 	and 	tdilc101.strs >  0.0  
	as set with 1 rows
 	selectdo
		return(true)
	endselect

	return(false)
}

function	void determine.blocked.quantity(	
			domain	tccwar		i.warehouse,
			domain	tdilc.loca	i.location,
			domain	tccprj		i.project,
			domain	tcitem		i.item,
			domain	tdltc.clot	i.lot,
			domain	tcdate		i.inventory.date,
			domain	tccuni		i.unit,
			domain	tcqst1		i.blocked.quantity,
			domain	tcqst1		i.allocated.quantity,
		ref	domain	tcqst1		o.process.blocked,
		ref	domain	tcqst1		o.manual.blocked)
{
	domain	tcqst1	approved.quantity

	o.process.blocked = 0.0
	o.manual.blocked = 0.0
	if i.blocked.quantity = 0.0 then
		return
	endif
	if lot.is.blocked(	i.project,
			i.item,
			"",		|* Container
			i.lot) then
		o.process.blocked = 0.0
		o.manual.blocked = i.blocked.quantity
		return
	endif

	if tdilc000.iilc = tcyesno.yes then 
		if location.is.blocked(	
				i.warehouse,
				i.location) then
			o.process.blocked = 0.0
			o.manual.blocked = i.blocked.quantity
			return
		endif
		if stock.point.is.blocked(	
				i.warehouse,
				i.location,
				i.project,
				i.item,
				"",		|* Container
				i.lot,
				i.inventory.date,
				i.unit) then
			o.process.blocked = 0.0
			o.manual.blocked = i.blocked.quantity
			return
		endif
	endif
	if inspection.location(	i.warehouse,
				i.location) then
		o.process.blocked = i.blocked.quantity - i.allocated.quantity
		if o.process.blocked > 0 then
			get.approved.quantity(	i.warehouse,
						i.location,
						i.project,
						i.item,
						"",		|* container
						i.lot,
						i.inventory.date,
						i.unit,
						approved.quantity)
			o.process.blocked = i.blocked.quantity - approved.quantity
		endif
		if o.process.blocked < 0 then
			o.process.blocked = 0
		endif
	else
		o.process.blocked = i.blocked.quantity
	endif
	o.manual.blocked = 0.0
}

function domain tcbool lot.is.blocked(	
			domain	tccprj		i.project,
			domain	tcitem		i.item,
			domain	tccuni		i.container,
			domain	tdltc.clot	i.lot)
{
	select	tdltc003.*
	from	tdltc003
	where	tdltc003._index1 = {	:i.project,
					:i.item,
					:i.container,
					:i.lot}
	as set with 1 rows
	selectdo
		return(true)
	endselect

	return(false)
}

function domain tcbool location.is.blocked(	
			domain	tccwar		i.warehouse,
			domain	tdilc.loca	i.location)
{
	select	tdilc009.*
	from	tdilc009
	where	tdilc009._index1 = {	:i.warehouse,
					:i.location}
	as set with 1 rows
	selectdo
		return(true)
	endselect

	return(false)
}

function domain tcbool stock.point.is.blocked(	
			domain	tccwar		i.warehouse,
			domain	tdilc.loca	i.location,
			domain	tccprj		i.project,
			domain	tcitem		i.item,
			domain	tccuni		i.container,
			domain	tdltc.clot	i.lot,
			domain	tcdate		i.inventory.date,
			domain	tccuni		i.unit)
{
	select	tdilc104.*
	from	tdilc104
	where	tdilc104._index1 = {	:i.warehouse,
					:i.location,
					:i.project,
					:i.item,
					:i.container,
					:i.lot,
					:i.inventory.date,
					:i.unit}
	as set with 1 rows
	selectdo
		return(true)
	endselect

	return(false)
}

function domain tcbool inspection.location(	
			domain	tccwar		i.warehouse,
			domain	tdilc.loca	i.location)
{
	domain	tdilc.loca	insp.location

	select	tdilc001.loca:insp.location
	from	tdilc001
	where	tdilc001._index1 = {	:i.warehouse,
					:i.location}
	and	tdilc001.aplo = tcyesno.yes
	as set with 1 rows
	selectdo
		return(true)
	endselect

	return(false)
}

function void get.approved.quantity(	
			domain	tccwar		i.warehouse,
			domain	tdilc.loca	i.location,
			domain	tccprj		i.project,
			domain	tcitem		i.item,
			domain	tccuni		i.container,
			domain	tdltc.clot	i.lot,
			domain	tcdate		i.inventory.date,
			domain	tccuni		i.unit,
		ref	domain	tcqst1		o.approved.quantity)
{
	o.approved.quantity = 0.0

	select	sum(tdilc111.stra):o.approved.quantity
	from	tdilc111
	where	tdilc111._index2 = {	:i.warehouse,
					:i.location,
					:i.project,
					:i.item,
					:i.container,
					:i.lot,
					:i.unit,
					:i.inventory.date}
	as set with 1 rows
	selectdo
	endselect
}

function domain	tcbool fifo.lifo.item(
			domain	tccprj	i.project,
			domain	tcitem	i.item)
{
	domain	tcobpr	outbound.priority

	if isspace(i.project) then
		select  	tiitm001.obpr:outbound.priority  
	  	from  	tiitm001  
 	  	where  	tiitm001._index1 =  {:i.item}  
		and	tiitm001.obpr = tcobpr.loca
 	  	as set with 1 rows  
	  	selectdo
			return(false)  
 	  	endselect
	else
		select  	tipcs021.obpr:outbound.priority  
	  	from  	tipcs021  
 	  	where  	tipcs021._index1 =  {	:i.project,
						:i.item}  
		and	tipcs021.obpr = tcobpr.loca
 	  	as set with 1 rows  
	  	selectdo  
			return(false)
 	  	endselect
	endif

	return(true)  
}

function domain tcbool item.revision.is.valid(
		domain	tcitem		i.item,
		domain	tiedm.revi	i.revision)
{
	select 	 tiedm100.*
	from 	 tiedm100
	where 	 tiedm100._index1 = {	:i.item,
					:i.revision}          
 	and 	 tiedm100.rele =  tiedm.rele.yes
	as set with 1 rows
	selectdo
 	 	 return(true)
 	 endselect

	return(false)
}

function	determine.location.allocated.quantity(
			domain	tccwar		i.warehouse,
			domain	tccprj		i.project,
			domain	tcitem		i.item,
			domain	tdltc.clot	i.lot,
		ref	domain	tcqiv1		o.location.allocated.quantity)
{
	|* PERF
	|       replace old query with full table scan by a query which is only once executed
	|      the warehouse + items + lot + sum(tdilc401,qsts) with proc=no are stored in a memory array
	|      it is expected that  there is only a small percentage of records in tdilc401 with proc=no

	static	domain	tcitem	cwar_item_lot_array(1) based	| item array
	static	domain	tcqiv1	qsts_array(1) based		| sum(tdilc401.qsts) array
	
	static	long 	array.size		| current size of the array
	static	long 	array.index		| current index in the array
		long	result			| result of search
	static	long	table.read		| static for table tdicl401 has been read
	long	search_def(1,4)			| qss search definition
	long	length.of.item
	long	length.of.lot
	long	length.of.warehouse	
	long 	dummy.long

	if not table.read then
		if length.of.item = 0 then
			rdi.domain.string("tcitem", length.of.item, dummy.long)
			rdi.domain.string("tdltc.clot", length.of.lot, dummy.long)		
			rdi.domain.string("tccwar",length.of.warehouse, dummy.long)
		endif
		| clean array
		if array.index > 0 then
			set.mem(cwar_item_lot_array,"")
			array.index = 0
		endif

		| fill array for new warehouse
		select	sum(tdilc401.qsts):o.location.allocated.quantity,tdilc401.cwar,tdilc401.item,tdilc401.clot   
		from	tdilc401  
		where	tdilc401.proc =  tcyesno.no
		and 	tdilc401.qsts >  0.0  
		group by tdilc401.cwar,tdilc401.item,tdilc401.clot
		selectdo
			| fill array 
			array.index = array.index + 1
			if array.index > array.size then
				| alloc (additional) memory
				array.size = array.size + 100
				alloc.mem(cwar_item_lot_array,length.of.warehouse+length.of.item+length.of.lot, array.size)	
				alloc.mem(qsts_array, array.size)
			endif
			| store item, lot and sum(tdilc401.qsts)
			cwar_item_lot_array(1,array.index) = tdilc401.cwar
			cwar_item_lot_array(1+length.of.warehouse,array.index) = tdilc401.item
			cwar_item_lot_array(1+length.of.warehouse+length.of.item,array.index) = tdilc401.clot
			qsts_array(array.index) = o.location.allocated.quantity			
		selectempty
			| no values found with delivered = no
		endselect
		table.read = true
	endif

	| search array for values
	if array.index = 0 then
		o.location.allocated.quantity = 0.0
	else
		qss.start(search_def,1,1)
		qss.way(search_def,1,QSS.UP)
		qss.type(search_def,1,DB.STRING)
		qss.length(search_def,1,length.of.warehouse+length.of.item+length.of.lot)
		result = qss.search(QSS.EQUAL,i.warehouse&i.item&i.lot,cwar_item_lot_array,search_def,array.index)
		if result > 0 then
			o.location.allocated.quantity = qsts_array(result)
		else
			o.location.allocated.quantity = 0.0
		endif
	endif

|	o.location.allocated.quantity = 0.0	
|	select	sum(tdilc401.qsts):o.location.allocated.quantity   
|	from	tdilc401  
|	where	tdilc401.proc =  tcyesno.no
|	and	tdilc401.cwar = :i.warehouse  
|	and 	tdilc401.item = :i.item
|	and	tdilc401.clot = :i.lot                                
|	and 	tdilc401.qsts >  0.0  
|	as set with 1 rows
|	selectdo  
|	endselect
}

function dump.cost.details()
{
	if not isspace(var.whltc101.cpcp) then
		Dump 2
	endif
}  

|********************
:FUNC:END
:TEXT:

:TEXT:END
FUNC160
:MPRF:19
:VERS:B40U
:RELE:c4
:CUST:cont
:TCPAC:wh
:TCMOD:wmd
:TFLNO:215
:FUNC:START
function migrate.distribution.item.data.by.warehouse()
{
 	 	 | *  only items of item type purchased or manufactured are converted.  
 	 	 | *  item type (project) should not be equipment or subcontracting.  
 	 	 | *  so only type (project) item is dumped.  

	select 	 tdinv001.* , tcmcs003.sloc,
	 	 tiitm001.item, tiitm001.kitm, tiitm001.ltcp,
		tiitm001.stva,					|#146674.n
		tiitm001.sftm,  tiitm001.abcc,  tiitm001.itmt  
	from 	 tdinv001, 
	 	 tcmcs003, 
	 	 tiitm001
	where 	 tdinv001.cwar > ""
	 and 	 tdinv001.cntr = ""
	 and 	 tcmcs003._index1 = {tdinv001.cwar}
	 and 	 tcmcs003.typw <> tctypw.transito
	 and 	 tiitm001._index1 = {tdinv001.item}
	 and 	 (tiitm001.kitm = tckitm.purchase or
	 	 tiitm001.kitm = tckitm.manufacture ) 	
	 and 	 tiitm001.itmt = tppdm.itmt.item
	selectdo
		create.item.by.warehouse()
		 create.inventory()
	 	 create.inventory.cost.details()
	endselect
}

function create.item.by.warehouse()
{
	if (tdinv001.maxs >  99999999) then  
 	 	 tdinv001.maxs =  99999999  
 	 endif  
 	 var.whwmd210.item =  segment.item.code( 	 tdinv001.item,  
 	 	 	 	 	 	 	 "")    
 	 if tdinv001.oqmf >  0 then  
 	 	 var.whwmd210.oqmf =  tdinv001.oqmf  
 	 else  
 	 	 var.whwmd210.oqmf =  1.0  
 	 endif  
 	 	 	 	 	 	 	 	 | #  800 -  142003.sn  
	default.location.type()
 	 	 	 	 	 	 	 	 | #  800 -  142003.en  
 	 var.whwmd210.sftm =  tiitm001.sftm  
 	 var.whwmd210.abcc =  tiitm001.abcc
								|#146674.sn
	if tiitm001.stva = tcstva.lot.price then
		if lot.controlled.item("", tdinv001.item) then
			var.whwmd210.valm = 5	|* target lot price
		else
			var.whwmd210.valm = 1	|* target FTP
		endif
	else
		var.whwmd210.valm = 1	|* target FTP
	endif
								|#146674.en

	dump 210
}

function default.location.type()
{
 	 | *  determine default location type for inbound advice.  
 	 if tcmcs003.sloc =  tcyesno.yes then  
 	 	 var.whwmd210.ialt =  5 | *  whwmd.loct.bulk  
 	 else  
 	 	 var.whwmd210.ialt =  20 | *  whwmd.loct.not.appl  
 	 endif  
}

function create.inventory()
{
	var.whwmd215.cwar = tdinv001.cwar
	var.whwmd215.item = segment.item.code(
					tdinv001.item,
					"")	|* Project
	if is.masterdata.conversion() then
		init.inventory.fields()
	else
		var.whwmd215.qhnd = tdinv001.stoc
		var.whwmd215.qchd = 0.0
		set.quantities.blocked(
				tdinv001.cwar,
				tdinv001.item,
				tdinv001.blck,
				tdinv001.qbsi)
		var.whwmd215.qord = tdinv001.ordr
		var.whwmd215.qcor = 0.0
		var.whwmd215.qint = 0.0
		set.quantities.allocated.and.onorder()
		var.whwmd215.qcal = 0.0
		var.whwmd215.qcom = tdinv001.hall
		if tdilc000.iilc = tcyesno.yes then
			determine.location.allocated.quantity(
					tdinv001.cwar,
					"", |*  Project
					tdinv001.item,
					var.whwmd215.qlal)
		else
			var.whwmd215.qlal = 0.0
		endif
		var.whwmd215.qcpr = 0.0
		var.whwmd215.ltdt = utc(tdinv001.ltdt, 0)
		var.whwmd215.hstd = utc(tdinv001.hstd, 0)
		var.whwmd215.lsid = utc(tdinv001.lsid, 0)
		var.whwmd215.qcis = tdinv001.uscu
		var.whwmd215.qhib = tdinv001.hstb
	endif
	
	dump 215	| * whwmd215 - Item Inventory by Warehouse
	dump 216	| * whwmd216 - Inventory by Warehouse, Item and Eff.Unit
	
}

function init.inventory.fields()
{
	var.whwmd215.qhnd = 0.0
	var.whwmd215.qchd = 0.0
	var.whwmd215.qblk = 0.0
	var.whwmd215.qbpl = 0.0
	var.whwmd215.qord = 0.0
	var.whwmd215.qcor = 0.0
	var.whwmd215.qint = 0.0
	var.whwmd215.qall = 0.0
	var.whwmd215.qcal = 0.0
	var.whwmd215.qcom = 0.0
	var.whwmd215.qlal = 0.0
	var.whwmd215.qcpr = 0.0
	var.whwmd215.ltdt = utc(0,0)
	var.whwmd215.hstd = utc(0,0)
	var.whwmd215.lsid = utc(0,0)
	var.whwmd215.qcis = 0.0
	var.whwmd215.qhib = 0.0
}

function set.quantities.blocked(
	domain	tccwar	i.warehouse,
	domain	tcitem	i.item,
	double		i.qty.blocked,
	double		i.qty.blocked.for.inspection)
{
	var.whwmd215.qblk = i.qty.blocked + i.qty.blocked.for.inspection
	if tdilc000.iilc = tcyesno.yes and
	   var.whwmd215.qblk > 0.0 then
		determine.blocked.quantity.decrease(
			i.warehouse, 
			"", 	|* Project
			i.item, 
			blocked.quantity.decrease)
		if blocked.quantity.decrease > 0.0 then
			var.whwmd215.qblk = var.whwmd215.qblk - 
						blocked.quantity.decrease
			if var.whwmd215.qblk < 0.0 then
				var.whwmd215.qblk = 0.0
			endif
		endif				 
	endif
	var.whwmd215.qbpl = var.whwmd215.qblk 
}

function set.quantities.allocated.and.onorder()
{
	if tipcs000.ipcs = tcyesno.yes then
		| * PCS implemented 
		var.whwmd215.qall = 
			determine.prp.inv.correction.for.standard.item( 
					tdinv001.item, 
					tdinv001.cwar, 
					tdinv001.allo) 
	else 
		var.whwmd215.qall = tdinv001.allo 
	endif 
 
	| * Purhase return order in Baan4 creates a negative on order quantity, 
	| * In Baan6 it must be a positive allocated quantity. 
	| * Sales return order in Baan4 creates a negative allocated quantity, 
	| * In Baan6 it must be a positive on order quantity. 

	move.to.allocated = 0.0 
	move.to.onorder = 0.0 
	if var.whwmd215.qord < 0.0 then 
		move.to.allocated = abs(var.whwmd215.qord) 
	endif 
	if var.whwmd215.qall < 0.0 then 
		move.to.onorder = abs(var.whwmd215.qall) 
	endif 
	if move.to.allocated +  move.to.onorder > 0.0 and 
	  move.to.allocated <> move.to.onorder then  
		if move.to.allocated > move.to.onorder then 
			move.to.allocated = move.to.allocated - move.to.onorder 
			var.whwmd215.qord = 0.0 
			var.whwmd215.qall = var.whwmd215.qall + move.to.allocated 
		else 
			move.to.onorder = move.to.onorder - move.to.allocated 
			var.whwmd215.qall = 0.0 
			var.whwmd215.qord = var.whwmd215.qord + move.to.onorder		 
		endif 
	endif 
}

function create.inventory.cost.details()
{
	date.last.cost.price.change = tiitm001.ltcp 
	| * Initialize variables. 
	initialize.ftpa.amounts() 
	| * Read standard cost price table. 
|	select	ticpr300.cpcp, 						|#CNT.so
|		ticpr300.amnt 						|#CNT.eo
	select	ticpr300.*						|#CNT.n
	from	ticpr300 
	where	ticpr300._index1 = {:tdinv001.item} 
	and	ticpr300.indt = :date.last.cost.price.change  
	selectdo
									|#CNT.sn
		for i = 1 to g.mc.depth
			amount.per.cc(i) = get.amount.per.cost.component(
						"ticpr300",
						i)
		endfor
									|#CNT.en 
		create.detailed.inventory.cost.details(
					tdinv001.item,
					"",	|* project
					ticpr300.cpcp, 
					amount.per.cc)			|#CNT.n
|					ticpr300.amnt)			|#CNT.o
	selectempty 
		| * No cost components, use aggregated components with ftp = 0. 
		material.component = bcstc000.matc 
		operation.component = bcstc000.oprc 
		surcharge.component = bcstc000.surc 
		initialize.ftpa.amounts()
	endselect 
	
	create.remainder.inventory.cost.details()
}

function domain tcqiv1 determine.prp.inv.correction.for.standard.item(
			domain	tcitem	i.item,
			domain	tccwar	i.warehouse,
			domain	tcqiv1	i.old.allo.quantity)
{
	|FunctionUsage
	|Expl:	In Baan IV when a planned PRP production order has a standard
	|	item as material, an inventory transaction is logged in tdinv150
	|	with Order Type = PRP Production Order and Transaction
	|	Type = - (negative). This leads to an increase of the Allocated 
	|	Inventory in tiitm001. But in Baan 6 inventory transactions
	|	for planned production orders are not logged in whinp100, but 
	|	only in cprrp010. These transactions are not reflected in the
	|	inventory data in tcibd100 and whwmd215. This means that the Allocated
	|	Inventory in tiitm001 needs to be adjusted for these type
	|	of transactions.
	|EndFunctionUsage

	domain	tcqiv1	prp.allocated.inventory

	prp.allocated.inventory = 0.0

	select	sum(tdinv150.qana):prp.allocated.inventory
	from	tdinv150
	where	tdinv150._index4 = {	:i.item,
					"",
					:i.warehouse}
	and	tdinv150.koor = tckoor.pcs.sfc
	and	tdinv150.kotr = tckotr.requirement
	selectdo
	endselect

	return(i.old.allo.quantity - prp.allocated.inventory)
}

function initialize.ftpa.amounts()
{
	e = set.mem(material.component.ftpa, 0)
	e = set.mem(operation.component.ftpa, 0)
	e = set.mem(surcharge.component.ftpa, 0)
}

function void	determine.blocked.quantity.decrease(
			domain	tccwar	i.warehouse,
			domain	tccprj	i.project,
			domain	tcitem	i.item,
		ref	domain	tcqiv1	o.blocked.quantity.decrease)
{
	domain	tdilc.loca	insp.location
	domain	tcqiv1		process.blocked.quantity
	domain	tcqiv1		approved.quantity

	o.blocked.quantity.decrease = 0.0
	select	tdilc101.*,
		tdilc001.loca:insp.location
	from	tdilc101, tdilc001
	where	tdilc101._index4 = {	:i.warehouse,
					:i.project,
					:i.item}
	and	tdilc101.cntr = ""
	and	tdilc101.loca <> ""
	and	tdilc101.stkb > 0.0
	and	tdilc001._index1 = {	tdilc101.cwar,
					tdilc101.loca}
	and	tdilc001.aplo = tcyesno.yes
	selectdo
		process.blocked.quantity = tdilc101.stkb - tdilc101.stka
		if process.blocked.quantity > 0 then
			get.approved.quantity(	tdilc101.cwar,
						tdilc101.loca,
						tdilc101.cprj,
						tdilc101.item,
						"",		|* container
						tdilc101.clot,
						tdilc101.date,
						tdilc101.stun,
						approved.quantity)
			process.blocked.quantity = tdilc101.stkb - approved.quantity
		endif
		if process.blocked.quantity < 0 then
			process.blocked.quantity = 0
		endif
		o.blocked.quantity.decrease = o.blocked.quantity.decrease +
				(tdilc101.stkb - process.blocked.quantity)
	endselect
}

function void get.approved.quantity(	
			domain	tccwar		i.warehouse,
			domain	tdilc.loca	i.location,
			domain	tccprj		i.project,
			domain	tcitem		i.item,
			domain	tccuni		i.container,
			domain	tdltc.clot	i.lot,
			domain	tcdate		i.inventory.date,
			domain	tccuni		i.unit,
		ref	domain	tcqst1		o.approved.quantity)
{
	o.approved.quantity = 0.0

	select	sum(tdilc111.stra):o.approved.quantity
	from	tdilc111
	where	tdilc111._index2 = {	:i.warehouse,
					:i.location,
					:i.project,
					:i.item,
					:i.container,
					:i.lot,
					:i.unit,
					:i.inventory.date}
	as set with 1 rows
	selectdo
	endselect
}

function determine.location.allocated.quantity(
			domain	tccwar	i.warehouse,
			domain	tccprj	i.project,
			domain	tcitem	i.item,
		ref	domain	tcqiv1	o.location.allocated.quantity)
{
	|* PERF
	|    replace old query by query which is only once executed for each warehouse
	|	the items + sum(tdilc401,qsts) are stored in a memory array
	|	function must be called with input sorted index1 of tdinv001 (= sorted on cwar + item)

	static	domain	tcitem	item_array(1) based	| item array
	static	domain	tcqiv1	qsts_array(1) based	| sum(tdilc401.qsts) array
	
	static	long array.size		| current size of the array
	static	long array.index		| current index in the array

		long	result			| result of search
	static	domain	tccwar	s.warehouse	| static for warehouse
	static	domain tcitem	s.item		| static for item
	static	domain tcqiv1	s.o.location.allocated.quantity
	long	search_def(1,4)			| qss search definition
	long	length.of.item
	long	dummy.long

	| same input then return earlier value
	if s.warehouse = i.warehouse and 
	  s.item = i.item then
		o.location.allocated.quantity = s.o.location.allocated.quantity
		return
	endif

	if s.warehouse <> i.warehouse then
		if length.of.item = 0 then
			rdi.domain.string("tcitem", length.of.item, dummy.long)
		endif
		| clean array
		if array.index > 0 then
			set.mem(item_array,"")
			array.index = 0
		endif

		| fill array for new warehouse	
		select	sum(tdilc401.qsts):o.location.allocated.quantity,
			tdilc401.item 
		from	tdilc401 
		where	tdilc401.proc = tcyesno.no
		and	tdilc401.cwar = :i.warehouse 
		and	tdilc401.qsts > 0.0 
		group by tdilc401.item
		selectdo 
			| fill array 
			array.index = array.index + 1
			if array.index > array.size then
				| alloc (additional) memory
				array.size = array.size + 100
				alloc.mem(item_array, length.of.item, array.size)	
				alloc.mem(qsts_array, array.size)
			endif
			| store item and sum(tdilc401.qsts)
			item_array(1,array.index) = tdilc401.item
			qsts_array(array.index) = o.location.allocated.quantity			
		selectempty
			| no values found with delivered = no
		endselect
		s.warehouse = i.warehouse
	endif

	| search array for values
	if array.index = 0 then
		o.location.allocated.quantity = 0.0
	else
		qss.start(search_def,1,1)
		qss.way(search_def,1,QSS.UP)
		qss.type(search_def,1,DB.STRING)
		qss.length(search_def,1,length.of.item)
		result = qss.search(QSS.EQUAL,i.item,item_array,search_def,array.index)
		if result > 0 then
			o.location.allocated.quantity = qsts_array(result)
		else
			o.location.allocated.quantity = 0.0
		endif
	endif

	s.item = i.item
	s.o.location.allocated.quantity = o.location.allocated.quantity

|	o.location.allocated.quantity = 0.0	
|	select	sum(tdilc401.qsts):o.location.allocated.quantity  
|	from	tdilc401 
|	where	tdilc401.proc = tcyesno.no
|	and	tdilc401.cwar = :i.warehouse 
|	and	tdilc401.item = :i.item    
|	and	tdilc401.qsts > 0.0
|	as set with 1 rows
|	selectdo
|	endselect
}


|********* MIGRATE FROM TIPCS021 ******************

function migrate.project.item.data.by.warehouse()
{
	select 	 tipcs021.* , tipcs020.prtp, tcmcs003.sloc
	from 	 tipcs021, tipcs020, tcmcs003
	where 	 tipcs020._index1 = {tipcs021.cprj}  
	and	tcmcs003.cwar = tipcs021.cwar
	selectdo  
		if tipcs020.prtp = tcyesno.yes then  
			skip.record = false  
			select 	 tppdm605.itmt  
			from 	 tppdm605  
			where 	 tppdm605._index1 = {:tipcs021.cprj, :tipcs021.item}  
			and 	 tppdm605.itmt = tppdm.itmt.item  
			and 	 tppdm605.prit <> tppdm.prit.manufactured  
			as set with 1 rows  
			selectdo  
			selectempty  
				skip.record = true  
			endselect  
			if skip.record then  
				continue  
			endif  
		endif  
		create.item.by.warehouse.from.project()
		create.inventory.from.project()  
		create.inventory.cost.details.from.project()  
	endselect  
}

function create.item.by.warehouse.from.project()
{
	default.location.type()
 	 g.new.project.code =  get.project(tipcs021.cprj)  
 	 var.whwmd210.item =  segment.item.code( 	 tipcs021.item,  
 	 	 	 	 	 	 	 g.new.project.code)  
 	 var.whwmd210.valm = 1	|* FTP				|#146674.n

	dump 211
}

function create.inventory.from.project()
{
	var.whwmd215.cwar = tipcs021.cwar  
	g.new.project.code = get.project(tipcs021.cprj)  
	var.whwmd215.item = segment.item.code(	tipcs021.item, 
						g.new.project.code)  
	if is.masterdata.conversion() then  
		init.inventory.fields()
	else  
		var.whwmd215.qhnd = tipcs021.stoc  
		var.whwmd215.qchd = 0.0
		set.quantities.blocked(
				tipcs021.cwar,
				tipcs021.item,
				tipcs021.blck,
				0.0)	|* blocked for inspection
		var.whwmd215.qord = tipcs021.ordr  
		var.whwmd215.qcor = 0.0  
		var.whwmd215.qint = 0.0  
		var.whwmd215.qall = tipcs021.allo  
		var.whwmd215.qcal = 0.0  
		var.whwmd215.qcom = tipcs021.hall  
		if tdilc000.iilc = tcyesno.yes then  
			determine.location.allocated.quantity(  
					tipcs021.cwar, 
					tipcs021.cprj, 
					tipcs021.item, 
					var.whwmd215.qlal)  
		else  
			var.whwmd215.qlal = 0.0  
		endif  
		var.whwmd215.qcpr = 0.0  
		var.whwmd215.ltdt = utc(tipcs021.ltdt, 0)  
		var.whwmd215.hstd = utc(0, 0)  
		var.whwmd215.lsid = utc(0, 0)  
		var.whwmd215.qcis = tipcs021.uscu  
		var.whwmd215.qhib = 0.0  
	endif  
	
	dump 215	| *  whwmd215 -  Item Inventory by Warehouse  
	dump 216	| *  whwmd216 -  Inventory by Warehouse, Item and Eff.Unit  
	
}

function create.inventory.cost.details.from.project()
{
	initialize.ftpa.amounts()  

	| *  Read cost price by customized table.  
|	select	tipcs350.cpcp, 						|#CNT.so
|		tipcs350.amte  						|#CNT.eo
	select	tipcs350.*
	from	tipcs350  
	where	tipcs350._index1 = { :tipcs021.cprj, :tipcs021.item }  
	selectdo  
									|#CNT.sn
		for i = 1 to g.mc.depth
			amount.per.cc(i) = get.amount.per.cost.component(
						"tipcs350",
						i)
		endfor
									|#CNT.en 
		create.detailed.inventory.cost.details(
				tipcs021.item,
				tipcs021.cprj,
				tipcs350.cpcp, 
				amount.per.cc)				|#CNT.n
|				tipcs350.amte)				|#CNT.o

	endselect  

	create.remainder.inventory.cost.details()	
}

|* call of function create.detailed.inventory.cost.details() always before 
|* call of function create.remainder.inventory.cost.details()
function create.detailed.inventory.cost.details(
			domain	tcitem	i.item,
			domain	tccprj	i.project,
			domain	tccpcp	i.cost.component,
		ref	domain	tccopr	i.amount())
|			domain	tccopr	i.amount)			|#CNT.o
{
									|#CNT.so
|	analyze.cost.component(	tipcs021.item,
|				tipcs021.cprj,
|				tipcs350.cpcp,
|				detail.cost.component, 
|				material.component, 
|				operation.component, 
|				surcharge.component, 
|				result)  
									|#CNT.eo
									|#CNT.sn
	analyze.cost.component(	i.item,
				i.project,
				i.cost.component,
				detail.cost.component, 
				material.component, 
				operation.component, 
				surcharge.component, 
				result)  
									|#CNT.en
	on case result  
	case 0:  
		| *  Cost Component in chart  
		| *  Detail Cost Component  
		var.whwmd217.cpcp = detail.cost.component  
		for i = 1 to g.mc.depth  
									|#CNT.so
|			var.whwmd217.ftpa(i) =
|				fill.mc.field.double(tipcs350.amte, i)  
									|#CNT.eo
			var.whwmd217.ftpa(i) = i.amount(i)		|#CNT.n
		endfor	 
		if is.masterdata.conversion() then  
			e = set.mem(var.whwmd217.mauc, 0)
		else
			e = copy.mem(	var.whwmd217.mauc(i),
					var.whwmd217.ftpa(i),
					g.mc.depth)
		endif  
		
		dump 217 | *  whwmd217 -  Item Inventory by Warehouse Cost Details
		break  
	case 1:  
		| *  Merge to aggregated material cost component  
		for i = 1 to g.mc.depth  
|			material.component.ftpa(i) =  				|#CNT.eo
|				material.component.ftpa(i) +   
|				fill.mc.field.double(tipcs350.amte, i)  	|#CNT.eo
			material.component.ftpa(i) = 				|#CNT.sn
				material.component.ftpa(i) + i.amount(i)	|#CNT.en

		endfor  
		break  
	case 2:  
		| *  Merge to aggregated opration cost component  
		for i = 1 to g.mc.depth  
|			operation.component.ftpa(i) =  				|#CNT.so
|				operation.component.ftpa(i) +   
|				fill.mc.field.double(tipcs350.amte, i)  	|#CNT.eo
			operation.component.ftpa(i) = 				|#CNT.sn
				operation.component.ftpa(i) + i.amount(i)	|#CNT.en
		endfor  
		break  
	case 3:  
		| *  Merge to aggregated surcharge cost component  
		for i = 1 to g.mc.depth  
|			surcharge.component.ftpa(i) =  				|#CNT.so
|				surcharge.component.ftpa(i) +   
|				fill.mc.field.double(tipcs350.amte, i)  	|#CNT.eo
			surcharge.component.ftpa(i) = 				|#CNT.sn
				surcharge.component.ftpa(i) + i.amount(i)	|#CNT.en
		endfor  
		break  
	endcase
}

function create.remainder.inventory.cost.details()
{
	|* init the mauc value; overwrite if not masterdata conversion		 
	e = set.mem(var.whwmd217.mauc, 0)

	| *  Material Cost Component  
	var.whwmd217.cpcp = material.component
	e = copy.mem(var.whwmd217.ftpa, material.component.ftpa, g.mc.depth)

	if not is.masterdata.conversion() then
		e = copy.mem(var.whwmd217.mauc, var.whwmd217.ftpa, g.mc.depth)
	endif  
	
	dump 217 | *  whwmd217 -  Item Inventory by Warehouse Cost Details

	| *  Operation Cost Component  
	var.whwmd217.cpcp = operation.component  
	e = copy.mem(var.whwmd217.ftpa, operation.component.ftpa, g.mc.depth)

	if not is.masterdata.conversion() then  
		e = copy.mem(var.whwmd217.mauc, var.whwmd217.ftpa, g.mc.depth)
	endif  
	
	dump 217 | *  whwmd217 -  Item Inventory by Warehouse Cost Details

	| *  Surcharge Cost Component  
	var.whwmd217.cpcp = surcharge.component
	e = copy.mem(var.whwmd217.ftpa, surcharge.component.ftpa, g.mc.depth)

	if not is.masterdata.conversion() then
		e = copy.mem(var.whwmd217.mauc, var.whwmd217.ftpa, g.mc.depth)
	endif  
	
	dump 217 | *  whwmd217 -  Item Inventory by Warehouse Cost Details
}

function read.parameters()
{
select	tipcs000.*
from	tipcs000
as set with 1 rows
selectdo
endselect

select 	 tdilc000.iilc, tdilc000.take
from 	 tdilc000 
as set with 1 rows
selectdo 
endselect

select	bcstc000.*
from	bcstc000
as set with 1 rows
selectdo
endselect
}

function set.period.variables()
{
	if tdinv000.perl = tcperl.month then	
		var.whwmd210.ptyp = 3 |* month.
		var.whwmd210.nopr = 1 |* nr. of buckets per period.
	else					
		var.whwmd210.ptyp = 2 |* week
		var.whwmd210.nopr = 4 |* nr. of buckets per period.
	endif 
}
:FUNC:END
:TEXT:

:TEXT:END
