def check_past_payment(payments_root, payment_cycle): payment_dir = payment_dir_c(payments_root, payment_cycle) # legacy payments if os.path.isdir(payment_dir): return "Payment directory for cycle {} is present. No payment will be run for the cycle. Check '{}'".format( payment_cycle, payment_dir) # new payments are reported to csv files payment_file = payment_report_file_path(payments_root, payment_cycle, 0) if os.path.isfile(payment_file): return "Payment report for cycle {} is present. No payment will be run for the cycle. Check '{}'".format( payment_cycle, payment_file) payment_file_failed = payment_report_file_path(payments_root, payment_cycle, 1) if os.path.isfile(payment_file_failed): return "Payment failed report for cycle {} is present. No payment will be run for the cycle. Check '{}'".format( payment_cycle, payment_file_failed) payment_file_failed_bush = get_busy_file(payment_file_failed) if os.path.isfile(payment_file_failed_bush): return "Busy payment failed report for cycle {} is present. No payment will be run for the cycle. Check '{}'".format( payment_cycle, payment_file_failed_bush) return None # which means No past payment
def clean_failed_payment_reports(self, payment_cycle): # 1- generate path of a assumed failure report file # if it exists, remove it failure_report_file = payment_report_file_path(self.payments_dir, payment_cycle, 1) if os.path.isfile(failure_report_file): os.remove(failure_report_file) # 2- generate path of a assumed busy failure report file # if it exists, remove it failure_report_busy_file = get_busy_file(failure_report_file) if os.path.isfile(failure_report_busy_file): os.remove(failure_report_busy_file)
def clean_failed_payment_reports(self, payment_cycle, success): # 1- generate path of a assumed failure report file # if it exists and payments were successful, remove it failure_report_file = payment_report_file_path(self.payments_dir, payment_cycle, 1) if success and os.path.isfile(failure_report_file): os.remove(failure_report_file) # 2- generate path of a assumed busy failure report file # if it exists, remove it ### # remove file failed/cycle.csv.BUSY file; # - if payment attempt was successful it is not needed anymore, # - if payment attempt was un-successful, new failedY/cycle.csv is already created. # Thus failed/cycle.csv.BUSY file is not needed and removing it is fine. failure_report_busy_file = get_busy_file(failure_report_file) if os.path.isfile(failure_report_busy_file): os.remove(failure_report_busy_file)
def retry_failed_payments(self): logger.info("retry_failed_payments started") # 1 - list csv files under payments/failed directory # absolute path of csv files found under payments_root/failed directory failed_payments_dir = get_failed_payments_dir(self.payments_root) payment_reports_failed = [ os.path.join(failed_payments_dir, x) for x in os.listdir(failed_payments_dir) if x.endswith('.csv') ] logger.debug("Trying failed payments : '{}'".format( ",".join(payment_reports_failed))) # 2- for each csv file with name csv_report.csv for payment_failed_report_file in payment_reports_failed: logger.debug("Working on failed payment file {}".format( payment_failed_report_file)) # 2.1 - if there is a file csv_report.csv under payments/done, it means payment is already done if os.path.isfile( payment_failed_report_file.replace(PAYMENT_FAILED_DIR, PAYMENT_DONE_DIR)): # remove payments/failed/csv_report.csv os.remove(payment_failed_report_file) logger.debug( "Payment for failed payment {} is already done. Removing.". format(payment_failed_report_file)) # remove payments/failed/csv_report.csv.BUSY # if there is a busy failed payment report file, remove it. remove_busy_file(payment_failed_report_file) # do not double pay continue # 2.2 - if queue is full, wait for sometime # make sure the queue is not full while self.payments_queue.full(): logger.info("Payments queue is full. Wait for 30 seconds.") time.sleep(30) cycle = int( os.path.splitext( os.path.basename(payment_failed_report_file))[0]) # 2.3 read payments/failed/csv_report.csv file into a list of dictionaries with open(payment_failed_report_file) as f: # read csv into list of dictionaries dict_rows = [{key: value for key, value in row.items()} for row in csv.DictReader( f, delimiter='\t', skipinitialspace=True)] batch = PaymentRecord.FromPaymentCSVDictRows(dict_rows, cycle) # 2.4 put records into payment_queue. payment_consumer will make payments if batch: self.payments_queue.put(batch) else: logger.info("Nothing to pay.") # 2.5 rename payments/failed/csv_report.csv to payments/failed/csv_report.csv.BUSY # mark the files as in use. we do not want it to be read again # BUSY file will be removed, if successful payment is done os.rename(payment_failed_report_file, get_busy_file(payment_failed_report_file))