import os from datetime import datetime, timedelta import csv import time from lib_poslog import find_invoices_in_storeday from localconfig import * from stores import Stores import io import zipfile from pprint import pprint import urllib.request import json import tempfile import models SORTED_PATH = os.path.join(BASEPATH, "Sorted") ECOSIO_PATH = os.path.join(BASEPATH, "Ecosio") stores = Stores() def save_edate(yyyymmdd): if not TEST: with open(EARLIEST_DATE_FILE, 'w') as file: file.write(yyyymmdd) def load_edate(): yyyymmdd = '20260201' if os.path.exists(EARLIEST_DATE_FILE): with open(EARLIEST_DATE_FILE, 'r') as f: yyyymmdd = f.readline() return yyyymmdd def remove_duplicates_inplace(file_path): seen = set() # Create temporary file in same directory dir_name = os.path.dirname(file_path) with tempfile.NamedTemporaryFile( mode='w', newline='', encoding='utf-8', delete=False, dir=dir_name ) as temp_file: temp_path = temp_file.name with open(file_path, mode='r', newline='', encoding='utf-8') as infile: reader = csv.reader(infile) writer = csv.writer(temp_file) for row in reader: if not row: continue key = row[0] if key not in seen: seen.add(key) writer.writerow(row) # Replace original file with cleaned file os.replace(temp_path, file_path) def invoice_all_stores_for(YYYY, MM, DD, update_store_file=False): """ from CSV file "stores_to_invoice" (global: stores) Get all the stores who creates archive files for check for if processing is done/not if not: for all stores check if a invoice found is already processed/not if not: process invoice and write to the processing service: invoicenr, system-isues, data-issues processing results on a list of invoices, they should be save to the ecosio folder - a service will pick themn up if a date has completely been processed, write to the processing service: date, poslogged, ecosiod If there is any file in the folder-structure NOT in the csv file, add it to the csv and issue a warning Pick up all the stores from the csv files who are tagged to create-invoices ...and have those invoices created :param YYYY: year :param MM: month :param DD: date """ global process_results name_prexif = 'TST_' if TEST else '' # open the results file buyer_issues = 0 system_issues = 0 date = f"{YYYY}-{MM}-{DD}" # contents = json.loads(urllib.request.urlopen(INVOICE_SERVICE + f"getStatusOfDate/{YYYY}/{MM}/{DD}").read()) # if contents['status'] == 'pending': print(f"Invoicing for {YYYY} {MM} {DD}") for country in stores.all_countries(): for store in stores.stores_for(country): # try: # get the invoices that are good to sent, and the number of data-fails invoices, invoices_with_data_issues = find_invoices_in_storeday(store, YYYY, MM, DD) for invoice in invoices: contents = json.loads(urllib.request.urlopen(INVOICE_SERVICE + f"poslog/canBeConverted/{invoice.poslogid}").read()) if (contents['status'] == 'Ok') or TEST: with open(os.path.join(ECOSIO_PATH, f"{name_prexif}{country}_{invoice.poslogid}.xml"), "w", encoding="utf-8") as lfile: lfile.write(str(invoice)) if not TEST: contents = urllib.request.urlopen(INVOICE_SERVICE + f"poslog/isConverted/{invoice.poslogid}/{invoice.receipt_id()}/{invoice.country()}").read() # save status to service for invoice in invoices_with_data_issues: if not TEST: contents = urllib.request.urlopen(INVOICE_SERVICE + f"poslog/hasIssues/{invoice.poslogid}/{invoice.receipt_id()}/{invoice.country()}").read() buyer_issues += 1 # except: # log(f"Programming error while processing {store} {YYYY}-{MM}-{DD}", 3) # # something went dreadfully wrong: send state to service # system_issues += 1 if not TEST: contents = urllib.request.urlopen(INVOICE_SERVICE + f"setStatusOfDate/{YYYY}/{MM}/{DD}/{system_issues}/{buyer_issues}").read() if __name__ == '__main__': today = datetime.datetime.today().date() earliest_date_str = load_edate() earliest_date = datetime.datetime.strptime(earliest_date_str, "%Y%m%d").date() process_date = earliest_date while process_date <= today: year4 = process_date.strftime('%Y') # 4-digit year month = process_date.strftime('%m') # 2-digit month day = process_date.strftime('%d') # 2-digit day d = f"{year4}-{month}-{day}" invoice_all_stores_for(year4,month,day) process_date = process_date + timedelta(days=1) # in the broken buyers csv files, remove any duplicates that may have caused it with multiple runs remove_duplicates_inplace(BUYERS_BROKEN) contents = json.loads(urllib.request.urlopen(INVOICE_SERVICE + f"getNextProcessDate/{earliest_date_str}").read()) save_edate(contents['data'])