# This integrates 2 Aibes platforms into or from a different source into 1 platform
require 'net/http'
namespace :aibes_integration do

	desc "create transactions"
  	task :system_configurations => :environment do 
  		integrated_accounts = IntegratedCustomerAccount.group(:project_id)
  		integrated_stands = IntegratedCustomerAccount.all
  		integrated_stands.each do |account|
  			stand = Stand.find_by(stand_number: account.customer_account.property_number)
  			class_category = ClassCategory.find(stand.class_category_id)
  			property_class = PropertyClass.find(stand.property_class_id)
  			project = Project.find(stand.project_id)
  			sale_type = SaleType.find(stand.sale_type_id)
  			general_plan = GeneralPlan.find(stand.general_plan_id)
  			lender = GeneralPlan.find(stand.lender_id)
  			currency = Currency.find(stand.currency_id)
  			selling_currency = Currency.find(stand.selling_currency_id)
  			currency_class = CurrencyClass.find(stand.currency_class_id)
  			unless AibesStand.exists?(stand_number: stand.stand_number)
  				puts("*** dealing with #{stand.stand_number}")
  			end
  		end
  	end

	desc "create transactions"
  	task :create_stands => :environment do 
  		integrated_accounts = IntegratedCustomerAccount.group(:project_id)
  		integrated_stands = IntegratedCustomerAccount.all
  		integrated_stands.each do |account|
  			stand = Stand.find_by(stand_number: account.customer_account.property_number)
  			class_category = ClassCategory.find(stand.class_category_id)
  			property_class = PropertyClass.find(stand.property_class_id)
  			project = Project.find(stand.project_id)
  			sale_type = SaleType.find(stand.sale_type_id)
  			general_plan = GeneralPlan.find(stand.general_plan_id)
  			lender = GeneralPlan.find(stand.lender_id)
  			currency = Currency.find(stand.currency_id)
  			selling_currency = Currency.find(stand.selling_currency_id)
  			currency_class = CurrencyClass.find(stand.currency_class_id)
  			unless AibesStand.exists?(stand_number: stand.stand_number)
  				puts("*** dealing with #{stand.stand_number} - #{stand.id}")
  				AibesStand.create(
  					stand_number: stand.stand_number,
  					size: stand.size,
  					price_psm: stand.price_psm,
  					sale_value: stand.sale_value,
  					available: stand.available,
  					class_category_id: class_category&.id,
  					property_class_id: property_class&.id,
  					project_id: project&.id,
  					sale_type_id: sale_type&.id,
  					general_plan_id: general_plan&.id,
  					lender_id: lender&.id,
  					currency_id: currency&.id,
  					currency_class_id: currency_class&.id,
  					vat_inclusive: stand.vat_inclusive,
  					selling_currency_id: selling_currency&.id,
  					is_taxable: stand.is_taxable,
  					tenure: stand.tenure,
  					external_id: stand.id
  				)
  			else
  				existing_stand = AibesStand.find_by(stand_number: stand.stand_number)
  				puts("*** updating #{existing_stand.stand_number} - #{existing_stand.id}")
  				existing_stand.update_attribute(:external_id, stand.id)
  			end
  		end
  	end

	desc "create customers"
  	task :create_customers => :environment do 
  		# get the integrated accounts
  		@integrated_accounts = IntegratedCustomerAccount.not_integrated
  		@integrated_accounts.each_with_index do |integrated_account,i|
  			account = integrated_account.customer_account
  			customer = integrated_account.customer_account.customer
  			puts("**** #{customer.customer_name}")
  			puts("**** #{customer.customer_additionals}")
  			ActiveRecord::Base.transaction do
	  			aibes_customer = AibesCustomer.find_or_initialize_by(customer_name: customer.customer_name)
	  			aibes_customer.assign_attributes(
					firstname: customer.firstname,
					lastname: customer.lastname,
					idnumber: customer.idnumber,
					address_1: customer.address_1,
					address_2: customer.address_2,
					city: customer.city,
					mobile_1: customer.mobile_1,
					mobile_2: customer.mobile_2,
					phone: customer.phone,
					email: customer.email,
					employer_name: customer.employer_name,
					employment_type: customer.employment_type,
					salary: customer.salary,
					dob: customer.dob,
					sex: customer.sex,
					registration_date: customer.registration_date, 
					active: customer.active,
					customer_name: customer.customer_name,
					registration_number: customer.registration_number,
					customer_type_id: customer.customer_type_id,
					is_individual: customer.is_individual,
					middlename: customer.middlename,
					country: customer.country,
					id_type: customer.id_type,
					referral: customer.referral,
					country_based: customer.country_based,
					customer_group_id: customer.customer_group_id,
					user_id: customer.user_id,
					external_id: customer.id
	  				)
	  			aibes_customer.save!

	  			customer.customer_additionals.each do |customer_additional|
	  				additional = AibesCustomerAdditional.find_or_initialize_by(firstname: customer_additional.firstname, lastname: customer_additional.lastname, idnumber: customer_additional.idnumber)
	  				additional.assign_attributes(
	  					customer_id: aibes_customer.id,
						firstname: customer_additional.firstname,
						lastname: customer_additional.lastname,
						idnumber: customer_additional.idnumber,
						address_1: customer_additional.address_1,
						address_2: customer_additional.address_2,
						city: customer_additional.city,
						mobile_1: customer_additional.mobile_1,
						mobile_2: customer_additional.mobile_2,
						phone: customer_additional.phone,
						email: customer_additional.email,
						dob: customer_additional.dob,
						sex: customer_additional.sex,
						active: customer_additional.active,
						middlename: customer_additional.middlename,
						country: customer_additional.country,
						id_type: customer_additional.id_type
	  				)
	  				additional.save!
	  			end
	  		end
  		end
  	end

	desc "create customers"
  	task :create_customer_accounts => :environment do 
  		# get the integrated accounts
  		@integrated_accounts = IntegratedCustomerAccount.not_integrated
  		# @integrated_accounts = IntegratedCustomerAccount.where(customer_account_id: 204)
  		@integrated_accounts.each_with_index do |integrated_account,i|
  			account = integrated_account.customer_account 
  			stand = AibesStand.find_by(external_id: account.stand_id)
  			customer = AibesCustomer.find_by(external_id: account.customer_id)
  			puts("*** #{i+=1} #{account.id} Allocating #{stand.stand_number} to #{customer.customer_name}")

  			ActiveRecord::Base.transaction do
  				aibes_account = AibesCustomerAccount.find_or_initialize_by(stand_id: stand.id, customer_id: customer.id, deleted: false)
  				aibes_account.assign_attributes(
  					customer_id: customer.id,
  					stand_id: stand.id,
  					sale_type_id: account.sale_type_id,
  					stand_value: account.stand_value,
  					stand_value_psm: account.stand_value_psm,
  					deposit_amount: account.deposit_amount,
  					deposit_rate: account.deposit_rate,
  					original_loan_amount: account.original_loan_amount,
  					upfront_fees: account.upfront_fees,
  					number_of_years: account.number_of_years,
  					upfront_fee_rate: account.upfront_fee_rate,
  					loan_balance: account.loan_balance,
  					interest_rate: account.interest_rate,
  					registration_date: account.registration_date,
  					contract_start_date: account.contract_start_date,
  					contract_end_date: account.contract_end_date,
  					deleted: account.deleted,
  					account_name: account.account_name,
  					agent_id: account.agent_id,
  					stand_size: account.stand_size,
  					property_number:account.property_number,
  					account_number: account.account_number,
  					status: account.status,
  					lender_id: account.lender_id,
  					class_category_id: account.class_category_id,
  					property_class_id: account.property_class_id,
  					project_id: account.project_id,
  					currency_class_id: account.currency_class_id,
  					currency_id: account.currency_id,
  					property_value_discount: account.property_value_discount,
  					is_takeon: account.is_takeon,
  					takeon_date: account.takeon_date,
  					general_plan_id: account.general_plan_id,
  					deposit_tenor: account.deposit_tenor,
  					registration_year: account.registration_year,
  					purchase_year: account.purchase_year
  				)

  				aibes_account.save!
  				stand.update!(available: false)
  				# puts JSON.pretty_generate(aibes_account.attributes)

  				# post initial transactions
  				account.transactions.where("deleted = false AND transaction_type_id = 1 AND posted = true").each do |init|
  					init_transaction = AibesTransaction.find_or_initialize_by(customer_account_id: aibes_account.id, transaction_type_id: init.transaction_type_id, posted: true, transaction_date: init.transaction_date, loan_balance: init.loan_balance, fee_due: init.fee_due)
  					init_transaction.assign_attributes(
  						customer_account_id: aibes_account.id,
  						transaction_date: init.transaction_date,
  						month: init.month,
  						year: init.year,
  						loan_balance: init.loan_balance,
  						fee_due: init.fee_due,
  						total_paid: init.total_paid,
  						payment_type_id: init.payment_type_id,
  						payment_title_id: init.payment_title_id,
  						user_id: init.user_id,
  						posted: true,
  						suspense: false,
  						transaction_type_id: 1,
  						project_id: aibes_account.project_id,
  						lender_id: aibes_account.lender_id,
  						property_class_id: aibes_account.property_class_id,
  						class_category_id: aibes_account.class_category_id,
  						lock: true,
  						payment: false,
  						currency_class_id: init.currency_class_id,
  						currency_id: init.currency_id,
  						rate: init.rate,
  						provider: 'PREMISE',
  						agent_id: aibes_account.agent_id,
  						general_plan_id: aibes_account.general_plan_id,
  						payment_category_id: init.payment_category_id					
  					)
  					init_transaction.save!
  					# puts JSON.pretty_generate(init_transaction.attributes)
  				end

  				# post fees
  				account.customer_account_fees.each do |fee|
  					acc_fee = AibesCustomerAccountFee.find_or_initialize_by(customer_account_id: aibes_account.id, payment_title_id: fee.payment_title_id, deleted: false)
  					acc_fee.assign_attributes(
  						customer_account_id: aibes_account.id,
  						payment_title_id: fee.payment_title_id,
  						date_posted: fee.date_posted,
  						amount: fee.amount,
  						deleted: fee.deleted
  					)
  					acc_fee.save!
  					# puts JSON.pretty_generate(acc_fee.attributes)
  				end

  				# post receipts plus suspense
				receipt_number = AibesTransaction.where(transaction_type_id: 3, suspense: true).maximum(:receipt_number)
  				account.transactions.where("deleted = false AND transaction_type_id = 3 AND suspense = true AND posted = false").each do |t|
			  		receipt_number = receipt_number.next
  					acc_transaction = AibesTransaction.find_or_initialize_by(customer_account_id: aibes_account.id, transaction_type_id: t.transaction_type_id, transaction_date: t.transaction_date, amount: t.amount, payment_type_id: t.payment_type_id)
  					acc_transaction.assign_attributes(
  						customer_account_id: aibes_account.id,
  						transaction_date: t.transaction_date,
  						month: t.month,
  						year: t.year,
  						amount: t.amount,
  						fee_due: t.fee_due,
  						total_paid: t.total_paid,
  						payment_type_id: t.payment_type_id,
  						payment_title_id: t.payment_title_id,
  						receipt_number: receipt_number,
  						reference_number: receipt_number,
  						user_id: t.user_id,
  						posted: false,
  						suspense: true,
  						transaction_type_id: 3,
  						project_id: aibes_account.project_id,
  						lender_id: aibes_account.lender_id,
  						property_class_id: aibes_account.property_class_id,
  						class_category_id: aibes_account.class_category_id,
  						lock: true,
  						payment: true,
  						currency_class_id: t.currency_class_id,
  						currency_id: t.currency_id,
  						rate: t.rate,
  						provider: 'PREMISE',
  						agent_id: aibes_account.agent_id,
  						general_plan_id: aibes_account.general_plan_id,
  						payment_category_id: t.payment_category_id,
  						invoice_number: t.invoice_number						
  					)
  					acc_transaction.save!
  					# puts JSON.pretty_generate(acc_transaction.attributes)

  					suspense_transaction = AibesSuspenseAccount.find_or_initialize_by(customer_account_id: aibes_account.id, reference_number: acc_transaction.transaction_code, posted: true)
  					suspense_transaction.assign_attributes(
					    amount: acc_transaction.amount,
					    customer_account_id: acc_transaction.customer_account_id,
					    deleted: acc_transaction.deleted,
					    month: acc_transaction.month,
					    year: acc_transaction.year,
					    payment_title_id: acc_transaction.payment_title_id,
					    payment_type_id:acc_transaction.payment_type_id,
					    currency_id: acc_transaction.currency_id,
					    rate: acc_transaction.rate,
					    posted: true,
					    reversed: false,
					    receipt_number: acc_transaction.receipt_number,
					    reference_number: acc_transaction.transaction_code,
					    payment_category_id: acc_transaction.payment_category_id,
					    transaction_date: acc_transaction.transaction_date,
					    user_id: acc_transaction.user_id,
					    legal: acc_transaction.legal,
					    provider: acc_transaction.provider,
					    online_payment: false,
					    integrated: false,
					    journal: acc_transaction.journal,
					    journal_reference: acc_transaction.journal_reference,
					    journal_description: acc_transaction.journal_description,
					    authorised: true 						
  					)
  					suspense_transaction.save!
  					# puts JSON.pretty_generate(suspense_transaction.attributes)
  				end
  			end
  		end
  	end 	

	desc "create transactions"
  	task :transactions => :environment do 
  		# get integrated accounts transactions
  		AibesCustomerAccount.all.each do |aibes_account|
  			@customer_account = aibes_account
			initial_receipt = SystemSetting.find_by(config_key: "InitialReceiptNo").config_value
  			Transaction.where(customer_account_id: aibes_account.id, transaction_type_id: 3).each do |transaction|
  				unless AibesTransaction.exists?(transaction_code: transaction.transaction_code)
	  				puts("dealing with #{transaction.id} - #{transaction.customer_account_id} - #{transaction.amount}")
	  				@transaction = AibesTransaction.new
	  				@transaction.transaction_code = transaction.transaction_code
	  				@transaction.customer_account_id = @customer_account.id
	  				@last_payment = AibesTransaction.where(posted: false, transaction_type_id: 3).last
					if @last_payment.nil?
						@transaction.reference_number = initial_receipt
						@transaction.receipt_number = initial_receipt
					else
						@transaction.reference_number = @last_payment.reference_number.next
						@transaction.receipt_number = @last_payment.receipt_number.next
					end
				    @transaction.payment_type_id = transaction.payment_type_id
				    @transaction.currency_id = transaction.currency_id
				    @transaction.payment = transaction.payment
				    @transaction.legal = transaction.legal
				    @transaction.sms = transaction.sms
				    @transaction.currency_id = transaction.currency_id
				    @transaction.currency_class_id = transaction.currency_class_id
				    @transaction.transaction_date = transaction.transaction_date
				    @transaction.rate = transaction.rate
				    @transaction.amount = transaction.amount
				    @transaction.payment_title_id = transaction.payment_title_id
				    @transaction.payment_category_id = transaction.payment_category_id
				    @transaction.bank_id = transaction.bank_id
				    @transaction.bank_statement_desc = transaction.bank_statement_desc
				    @transaction.statement_reference_number = transaction.statement_reference_number
				    @transaction.posted = false
				    @transaction.journal = transaction.journal
				    @transaction.journal_description = transaction.journal_description
				    @transaction.journal_reference = transaction.journal_reference
				    @transaction.suspense = true
				    @transaction.user_id = transaction.user_id
				    @transaction.transaction_type_id = transaction.transaction_type_id
					if @transaction.save
						transaction = @transaction.id
						user = @transaction.user_id
						AibesSuspenseAccount.post_suspense_transaction(user,transaction)
					end
				end

  			end
  		end
  	end

  	
end