activity based

function calculateEmissionByActivity(activity: ActivityDTO) : {
	calculatedAt: Date;
	totalEmission: number;
	materialEmission?: number;
	transportationEmission?: number;
}
// Database `cccdb`
// Type: subcollection
// Collection name `activities`
// Schema version 1.0

interface calculatedEmissionSnapshot {
	calculatedAt: Date;
	totalEmission: number;
	materialEmission?: number;
	transportationEmission?: number;
}

export interface ActivityDTO {
	uid: string;
	emissionSource: string;
	
	activityRemark?: string;
	vcaNodeId?: string;
	batchId?: string;
	
	materialBased?: {
		materialResourceType: string;
		unitAmount: number;
		unit: string;
	};
	
	// either
	transportationDistanceBased?: {
		transportVehicleResourceType: string;
		transportWeight: number;
		transportDistance: number;
		transportDepartPercentage: number;
		transportArrivePercentage: number;
	};
	// or
	transportationFuelAmountBased?: {
		transportFuelResourceType: string;
		transportFuelUnitAmount: number;
		transportFuelUnit: string;
	};
	
	  
	
	allocation: {
		allocationType: 'no_allocation' // default
		| 'energy_based'
		| 'physical_based'
		| 'economic_based'
		| 'other';
		mainProduct?: number;
		coProduct?: number;
		allocationPercentage: number; // default = 100%
	};  
	
	recycle: {
		recycleType:
		| 'no_recycle'
		| 'primary_manual_input'
		| 'secondary_tgo_material_based';
		recycleMaterial?: 'rubber' | 'paper' | 'plastic';
		recycleRate: number;
	};
	
	calculatedEmission?: calculatedEmissionSnapshot[];

	createdAt: Date;
	updatedAt: Date;
}
// Database `cccdb`
// Type: subcollection
// Collection name `emissionfactors`
// Collection name `emissionfactors` can be a standalone collection as a global emission factor library
// Or
// Under collection `businesses`, say, a business can have multiple emission factors
// Schema version 1.0


export interface GlobalWarmingPotentialDto {
	uid: string;
	commonName: string;
	formulaName: string;
	gwp100yr: number;
}

interface CustomEFValue {
	gwpId: string;
	value: number;
}

export interface EmissionFactorDto {
	uid: string;
	name: string;
	source: 'self' | 'supplier' | 'TGO' | 'predefined';
	type: 'co2_only' | 'multiple_ghgs';
	value: number | CustomEFValue[];
	
	unit: {
		id: string;
		name: string;
	};
	
	isSupportingProcess?: boolean;
	date?: Date;
	status?: 'active' | 'inactive';
	stage: 'unverified' | 'verified' | 'verifing';
	belongTo?: string; // in case of self, supplier, or predefined emission factors

	createdAt: Date;
	updatedAt: Date;
}
Unit Converter

(input unitAmount, input unit, resourceType) -> (desiredUnitAmount, desiredUnit)

  1. convert to standard unit
    1. unit.toSI()
  2. if unit is not in the same category
    1. cross-category conversion
      1. if desired unit is weight and input unit is in volume
        1. desiredUnitAmount = unitAmount x resourceType.flexibilityOfUnit.density
      2. if desired unit is volume and input unit is in weight
        1. desiredUnitAmount = unitAmount / resourceType.flexibilityOfUnit.density
      3. if desired unit is power and input unit is in time
        1. desiredUnitAmount = unitAmount x resourceType.flexibilityOfUnit.powerConsumption
  3. unit.to(desiredUnit)

Flow

  1. get ActivityDTO from parameter
  2. set is materialEmission = 0, transportationEmission = 0
  3. calculate material based emission
    1. if materialBased
      1. lookup materialResourceType
      2. ef = materialResourceType.ef
      3. if ef.unit !== materialBased.unit
        1. unit converter
      4. materialEmission = convertedUnitAmount * ef.value
    2. else skip
  4. calculate transportation based emission
    1. if transportationDistanceBased
      1. select depart, arrival ef from transportVehicleResourceType, transportDepartPercentage, transportArrivePercentage -> look for it in system config json
      2. unit converter for transportWeight, transportDistance
      3. calculate depart load
        1. transportWeight x transportDistance
      4. calculate arrival load
        1. depart load / maximumLoadTonne
          4.transportationEmission = depart load x depart ef + arrival load x arrived ef
    2. else if transportationFuelAmountBased
      1. lookup transportFuelResourceType
      2. ef = transportFuelResourceType.ef
      3. if ef.unit !== transportFuelUnit
        1. unit converter
      4. transportationEmission = convertedUnitAmount * ef.value
    3. else skip
  5. recycle
    1. activity category = waste or eol
      1. if recycleType === no_recycle
      2. else if recycleType === primary_manual_input
        1. materialEmission = materialEmission x (1 - recycleRate)
      3. else if recycleType === secondary_tgo_material_based
        1. if recycleMaterial === rubber
          1. recycleRate = xx
        2. else if recycleMaterial === paper
          1. recycleRate = xx
        3. else if recycleMaterial === plastic
          1. recycleRate = xx
        4. materialEmission = materialEmission x (1 - recycleRate)
  6. allocation
    1. if allocationType === no_allocation skip
    2. else if allocationType === energy_based or physical_based or economic_based
      1. allocationPercentage = mainProduct / (mainProduct + coProduct)
    3. materialEmission = materialEmission x allocationPercentage
    4. transportationEmission = transportationEmission x allocationPercentage
  7. output
    1. timestamp
    2. totalEmission = materialEmission + transportationEmission
    3. materialEmission
    4. transportationEmission

transportation resourcetype config

[
	{
		transportVehicleResourceType: "รถบรรทุก 6 ล้อ ขนส่งแบบปกติ",
		maxmimumLoadTonne: 100, 
		efs: [
			{
				"loadPercentage": 100,
				// อาจจะ ref ไปหาตัวที่เก็บในระบบ
				"unitAmount": 2.34,
				"unit": "km"
			},
			{
				"loadPercentage": 75,
				"unitAmount": 2.34,
				"unit": "km"
			}
			...
		]
	}
	...
]

Yes

Yes

No

No

Distance based

Fuel amount based

Yes

No

None

Yes

No recycle

Primary manual input

Secondary TGO material based

Rubber

Paper

Plastic

No

No allocation

Energy/Physical/Economic based

Unit Converter

No

Weight to Volume

Volume to Weight

Time to Power

Yes

Input: unitAmount, unit, resourceType

Convert to standard unit

Units in same category?

Cross-category conversion

Use density

Use inverse density

Use powerConsumption

Convert to desired unit

Output: desiredUnitAmount, desiredUnit

Start

Get ActivityDTO

Set materialEmission = 0, transportationEmission = 0

Is materialBased?

Lookup materialResourceType

ef = materialResourceType.ef

ef.unit != materialBased.unit?

Unit Converter

materialEmission = amount * ef.value

Skip material emission

Transportation type?

Lookup transportVehicleResourceType

Get transportDepartPercentage

Get transportArrivePercentage

Get depart ef and arrive ef from system config

Calculate depart load: transportWeight * transportDistance

Get maximumLoadTonne from system config

Calculate arrival load: depart load / maximumLoadTonne

Calculate depart emission: depart load * depart ef

Calculate arrive emission: arrival load * arrive ef

transportationEmission = depart emission + arrive emission

Lookup transportFuelResourceType

ef = transportFuelResourceType.ef

ef.unit != transportFuelUnit?

Unit Converter

transportationEmission = amount * ef.value

Skip transportation emission

Is activity waste or EOL?

Recycle Type?

Skip recycle

materialEmission *= 1 - recycleRate

Recycle Material?

Set recycleRate for rubber

Set recycleRate for paper

Set recycleRate for plastic

materialEmission *= 1 - recycleRate

Skip recycle

Allocation Type?

Skip allocation

Calculate allocationPercentage

Apply allocation to emissions

Prepare output

Set timestamp

Calculate totalEmission

Output materialEmission

Output transportationEmission

End

batch based

function calculateEmissionByฺBatch(activity: BatchDTO) : {
	calculatedAt: Date; 
	totalEmission: number; 
	materialEmission?: number; 
	transportationEmission?: number; 
}
// Database `cccdb`
// Type: sub of subcollection
// Collection name `batches`
// Under collection `businesses` and sub collection `products` say, a product can have multiple batches

// Schema version 1.0 
// Define BatchDto interface 
export interface BatchDto { 
	// Unique identifier
	uid: string;
	// Batch data
	name?: string;
	startDate?: Date;
	endDate?: Date;
	durationInDays?: number;
	status: 'active' | 'inactive' | 'deleted';
	stage: 'created' | 'on_progress' | 'finalized';
	// Update
	activities: ActivityDTO[];
	// Metadata
	createdBy: string;
	createdAt: Date;
	updatedBy?: string;
	updatedAt: Date;
}

Flow

input:
(batch ID, Output JSON Structure)

  1. query data and aggregate into groups
    1. User request activities corresponding with Batch ID
    2. Lookup for batch with batch ID
    3. activities = batch.activities
    4. group activities by chainId
      1. for each group, group by vcaNodeId
  2. emission Calculation
    1. activities Level:
      1. use Activity Based Calculator
    2. subStages Level (Node)
      1. sum every activities
      2. output { totalSubstageEmissions, totalSubstageMaterialBasedEmissions, totalSubstageTransportationBasedEmissions}
    3. stages Level:
      1. sum every substages emission
      2. output {totalStageEmissions, totalStageMaterialBasedEmissions, totalStageTransportationBasedEmissions}
    4. batch level
      1. sum every stages emission
      2. output {timestamp, totalBatchEmissions, totalBatchMaterialBasedEmissions, totalBatchTransportationBasedEmissions}
Unsupported markdown: list
Unsupported markdown: list

Start

Input: Batch ID, Output JSON Structure

Query activities for Batch ID

Lookup batch with batch ID

activities = batch.activities

Group activities by chainId

For each chainId group, group by vcaNodeId

Activities Level Calculation

Use Activity Based Calculator

Substages Level Calculation

Sum emissions for all activities in substage

Output substage emissions

{ totalSubstageEmissions,
totalSubstageMaterialBasedEmissions,
totalSubstageTransportationBasedEmissions }

Stages Level Calculation

Sum emissions for all substages in stage

Output stage emissions

{ totalStageEmissions,
totalStageMaterialBasedEmissions,
totalStageTransportationBasedEmissions }

Batch Level Calculation

Sum emissions for all stages in batch

Output batch emissions

{ timestamp,
totalBatchEmissions,
totalBatchMaterialBasedEmissions,
totalBatchTransportationBasedEmissions }

End